mirror of
https://github.com/django-components/django-components.git
synced 2025-08-31 19:27:19 +00:00
fix: Fix broken JS execution order (#821)
* fix: fix broken js exec order * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * refactor: remove stale comment --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
parent
e88e3af27f
commit
be27c1c94d
15 changed files with 833 additions and 379 deletions
|
@ -78,3 +78,65 @@ class OtherComponent(Component):
|
|||
class Media:
|
||||
css = "style.css"
|
||||
js = "script.js"
|
||||
|
||||
|
||||
@register("check_script_order_in_js")
|
||||
class CheckScriptOrderInJs(Component):
|
||||
template = "<check_script_order>"
|
||||
|
||||
# We should be able to access the global variables set by the previous components:
|
||||
# Scripts:
|
||||
# - script.js - testMsg
|
||||
# - script2.js - testMsg2
|
||||
# Components:
|
||||
# - SimpleComponent - testSimpleComponent
|
||||
# - SimpleComponentNested - testSimpleComponentNested
|
||||
# - OtherComponent - testOtherComponent
|
||||
js: types.js = """
|
||||
globalThis.checkVars = {
|
||||
testSimpleComponent,
|
||||
testSimpleComponentNested,
|
||||
testOtherComponent,
|
||||
testMsg,
|
||||
testMsg2,
|
||||
};
|
||||
"""
|
||||
|
||||
|
||||
@register("check_script_order_in_media")
|
||||
class CheckScriptOrderInMedia(Component):
|
||||
template = "<check_script_order>"
|
||||
|
||||
class Media:
|
||||
js = "check_script_order.js"
|
||||
|
||||
|
||||
@register("alpine_test_in_media")
|
||||
class AlpineCompInMedia(Component):
|
||||
template: types.django_html = """
|
||||
<div x-data="alpine_test">
|
||||
ALPINE_TEST:
|
||||
<div x-text="somevalue"></div>
|
||||
</div>
|
||||
"""
|
||||
|
||||
class Media:
|
||||
js = "alpine_test.js"
|
||||
|
||||
|
||||
@register("alpine_test_in_js")
|
||||
class AlpineCompInJs(Component):
|
||||
template: types.django_html = """
|
||||
<div x-data="alpine_test">
|
||||
ALPINE_TEST:
|
||||
<div x-text="somevalue"></div>
|
||||
</div>
|
||||
"""
|
||||
|
||||
js: types.js = """
|
||||
document.addEventListener('alpine:init', () => {
|
||||
Alpine.data('alpine_test', () => ({
|
||||
somevalue: 123,
|
||||
}))
|
||||
});
|
||||
"""
|
||||
|
|
5
tests/e2e/testserver/testserver/static/alpine_test.js
Normal file
5
tests/e2e/testserver/testserver/static/alpine_test.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
document.addEventListener('alpine:init', () => {
|
||||
Alpine.data('alpine_test', () => ({
|
||||
somevalue: 123,
|
||||
}))
|
||||
});
|
16
tests/e2e/testserver/testserver/static/check_script_order.js
Normal file
16
tests/e2e/testserver/testserver/static/check_script_order.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
// We should be able to access the global variables set by the previous components:
|
||||
// Scripts:
|
||||
// - script.js - testMsg
|
||||
// - script2.js - testMsg2
|
||||
// Components:
|
||||
// - SimpleComponent - testSimpleComponent
|
||||
// - SimpleComponentNested - testSimpleComponentNested
|
||||
// - OtherComponent - testOtherComponent
|
||||
|
||||
globalThis.checkVars = {
|
||||
testSimpleComponent: globalThis.testSimpleComponent,
|
||||
testSimpleComponentNested: globalThis.testSimpleComponentNested,
|
||||
testOtherComponent: globalThis.testOtherComponent,
|
||||
testMsg: globalThis.testMsg,
|
||||
testMsg2: globalThis.testMsg2,
|
||||
};
|
|
@ -1,11 +1,29 @@
|
|||
from django.http import HttpResponse
|
||||
from django.urls import include, path
|
||||
from testserver.views import multiple_components_view, single_component_view
|
||||
from testserver.views import (
|
||||
alpine_in_body_vars_not_available_before_view,
|
||||
alpine_in_body_view,
|
||||
alpine_in_body_view_2,
|
||||
alpine_in_head_view,
|
||||
check_js_order_in_js_view,
|
||||
check_js_order_in_media_view,
|
||||
check_js_order_vars_not_available_before_view,
|
||||
multiple_components_view,
|
||||
single_component_view,
|
||||
)
|
||||
|
||||
urlpatterns = [
|
||||
path("single/", single_component_view, name="single"),
|
||||
path("multi/", multiple_components_view, name="multi"),
|
||||
path("", include("django_components.urls")),
|
||||
# Empty response with status 200 to notify other systems when the server has started
|
||||
path("poll/", lambda *args, **kwargs: HttpResponse("")),
|
||||
# Test views
|
||||
path("single/", single_component_view, name="single"),
|
||||
path("multi/", multiple_components_view, name="multi"),
|
||||
path("js-order/js", check_js_order_in_js_view),
|
||||
path("js-order/media", check_js_order_in_media_view),
|
||||
path("js-order/invalid", check_js_order_vars_not_available_before_view),
|
||||
path("alpine/head", alpine_in_head_view),
|
||||
path("alpine/body", alpine_in_body_view),
|
||||
path("alpine/body2", alpine_in_body_view_2),
|
||||
path("alpine/invalid", alpine_in_body_vars_not_available_before_view),
|
||||
]
|
||||
|
|
|
@ -49,3 +49,164 @@ def multiple_components_view(request):
|
|||
rendered_raw = template.render(Context({}))
|
||||
rendered = render_dependencies(rendered_raw)
|
||||
return HttpResponse(rendered)
|
||||
|
||||
|
||||
def check_js_order_in_js_view(request):
|
||||
template_str: types.django_html = """
|
||||
{% load component_tags %}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
{% component_css_dependencies %}
|
||||
</head>
|
||||
<body>
|
||||
{% component 'outer' variable='variable' %}
|
||||
{% component 'other' variable='variable_inner' / %}
|
||||
{% endcomponent %}
|
||||
{# check_script_order_in_media is AFTER the other components #}
|
||||
{% component 'check_script_order_in_js' / %}
|
||||
abc
|
||||
{% component_js_dependencies %}
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
template = Template(template_str)
|
||||
rendered_raw = template.render(Context({}))
|
||||
rendered = render_dependencies(rendered_raw)
|
||||
return HttpResponse(rendered)
|
||||
|
||||
|
||||
def check_js_order_in_media_view(request):
|
||||
template_str: types.django_html = """
|
||||
{% load component_tags %}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
{% component_css_dependencies %}
|
||||
</head>
|
||||
<body>
|
||||
{% component 'outer' variable='variable' %}
|
||||
{% component 'other' variable='variable_inner' / %}
|
||||
{% endcomponent %}
|
||||
{# check_script_order_in_media is AFTER the other components #}
|
||||
{% component 'check_script_order_in_media' / %}
|
||||
abc
|
||||
{% component_js_dependencies %}
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
template = Template(template_str)
|
||||
rendered_raw = template.render(Context({}))
|
||||
rendered = render_dependencies(rendered_raw)
|
||||
return HttpResponse(rendered)
|
||||
|
||||
|
||||
def check_js_order_vars_not_available_before_view(request):
|
||||
template_str: types.django_html = """
|
||||
{% load component_tags %}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
{% component_css_dependencies %}
|
||||
</head>
|
||||
<body>
|
||||
{# check_script_order_in_media is BEFORE the other components #}
|
||||
{% component 'check_script_order_in_media' / %}
|
||||
{% component 'outer' variable='variable' %}
|
||||
{% component 'other' variable='variable_inner' / %}
|
||||
{% endcomponent %}
|
||||
abc
|
||||
{% component_js_dependencies %}
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
template = Template(template_str)
|
||||
rendered_raw = template.render(Context({}))
|
||||
rendered = render_dependencies(rendered_raw)
|
||||
return HttpResponse(rendered)
|
||||
|
||||
|
||||
def alpine_in_head_view(request):
|
||||
template_str: types.django_html = """
|
||||
{% load component_tags %}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
{% component_css_dependencies %}
|
||||
<script defer src="https://unpkg.com/alpinejs"></script>
|
||||
</head>
|
||||
<body>
|
||||
{% component 'alpine_test_in_media' / %}
|
||||
{% component_js_dependencies %}
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
template = Template(template_str)
|
||||
rendered_raw = template.render(Context({}))
|
||||
rendered = render_dependencies(rendered_raw)
|
||||
return HttpResponse(rendered)
|
||||
|
||||
|
||||
def alpine_in_body_view(request):
|
||||
template_str: types.django_html = """
|
||||
{% load component_tags %}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
{% component_css_dependencies %}
|
||||
</head>
|
||||
<body>
|
||||
{% component 'alpine_test_in_media' / %}
|
||||
{% component_js_dependencies %}
|
||||
<script src="https://unpkg.com/alpinejs"></script>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
template = Template(template_str)
|
||||
rendered_raw = template.render(Context({}))
|
||||
rendered = render_dependencies(rendered_raw)
|
||||
return HttpResponse(rendered)
|
||||
|
||||
|
||||
# Same as before, but Alpine component defined in Component.js
|
||||
def alpine_in_body_view_2(request):
|
||||
template_str: types.django_html = """
|
||||
{% load component_tags %}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
{% component_css_dependencies %}
|
||||
</head>
|
||||
<body>
|
||||
{% component 'alpine_test_in_js' / %}
|
||||
{% component_js_dependencies %}
|
||||
<script src="https://unpkg.com/alpinejs"></script>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
template = Template(template_str)
|
||||
rendered_raw = template.render(Context({}))
|
||||
rendered = render_dependencies(rendered_raw)
|
||||
return HttpResponse(rendered)
|
||||
|
||||
|
||||
def alpine_in_body_vars_not_available_before_view(request):
|
||||
template_str: types.django_html = """
|
||||
{% load component_tags %}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
{% component_css_dependencies %}
|
||||
</head>
|
||||
<body>
|
||||
{% component 'alpine_test_in_js' / %}
|
||||
{# Alpine loaded BEFORE components JS #}
|
||||
<script src="https://unpkg.com/alpinejs"></script>
|
||||
{% component_js_dependencies %}
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
template = Template(template_str)
|
||||
rendered_raw = template.render(Context({}))
|
||||
rendered = render_dependencies(rendered_raw)
|
||||
return HttpResponse(rendered)
|
||||
|
|
|
@ -125,11 +125,7 @@ class ComponentMediaTests(BaseTestCase):
|
|||
self.assertInHTML('<link href="path/to/style.css" media="all" rel="stylesheet">', rendered)
|
||||
self.assertInHTML('<link href="path/to/style2.css" media="all" rel="stylesheet">', rendered)
|
||||
|
||||
# Command to load the JS from Media.js
|
||||
self.assertIn(
|
||||
"Components.unescapeJs(\\`&lt;script src=&quot;path/to/script.js&quot;&gt;&lt;/script&gt;\\`)",
|
||||
rendered,
|
||||
)
|
||||
self.assertInHTML('<script src="path/to/script.js"></script>', rendered)
|
||||
|
||||
def test_css_js_as_string(self):
|
||||
class SimpleComponent(Component):
|
||||
|
@ -146,12 +142,7 @@ class ComponentMediaTests(BaseTestCase):
|
|||
rendered = SimpleComponent.render()
|
||||
|
||||
self.assertInHTML('<link href="path/to/style.css" media="all" rel="stylesheet">', rendered)
|
||||
|
||||
# Command to load the JS from Media.js
|
||||
self.assertIn(
|
||||
"Components.unescapeJs(\\`&lt;script src=&quot;path/to/script.js&quot;&gt;&lt;/script&gt;\\`)",
|
||||
rendered,
|
||||
)
|
||||
self.assertInHTML('<script src="path/to/script.js"></script>', rendered)
|
||||
|
||||
def test_css_as_dict(self):
|
||||
class SimpleComponent(Component):
|
||||
|
@ -175,11 +166,7 @@ class ComponentMediaTests(BaseTestCase):
|
|||
self.assertInHTML('<link href="path/to/style2.css" media="print" rel="stylesheet">', rendered)
|
||||
self.assertInHTML('<link href="path/to/style3.css" media="screen" rel="stylesheet">', rendered)
|
||||
|
||||
# Command to load the JS from Media.js
|
||||
self.assertIn(
|
||||
"Components.unescapeJs(\\`&lt;script src=&quot;path/to/script.js&quot;&gt;&lt;/script&gt;\\`)",
|
||||
rendered,
|
||||
)
|
||||
self.assertInHTML('<script src="path/to/script.js"></script>', rendered)
|
||||
|
||||
def test_media_custom_render_js(self):
|
||||
class MyMedia(Media):
|
||||
|
@ -204,15 +191,8 @@ class ComponentMediaTests(BaseTestCase):
|
|||
|
||||
rendered = SimpleComponent.render()
|
||||
|
||||
# Command to load the JS from Media.js
|
||||
self.assertIn(
|
||||
"Components.unescapeJs(\\`&lt;script defer src=&quot;path/to/script.js&quot;&gt;&lt;/script&gt;\\`)",
|
||||
rendered,
|
||||
)
|
||||
self.assertIn(
|
||||
"Components.unescapeJs(\\`&lt;script defer src=&quot;path/to/script2.js&quot;&gt;&lt;/script&gt;\\`)",
|
||||
rendered,
|
||||
)
|
||||
self.assertIn('<script defer src="path/to/script.js"></script>', rendered)
|
||||
self.assertIn('<script defer src="path/to/script2.js"></script>', rendered)
|
||||
|
||||
def test_media_custom_render_css(self):
|
||||
class MyMedia(Media):
|
||||
|
@ -314,23 +294,10 @@ class MediaPathAsObjectTests(BaseTestCase):
|
|||
self.assertInHTML('<link css_tag href="path/to/style3.css" rel="stylesheet" />', rendered)
|
||||
self.assertInHTML('<link href="path/to/style4.css" media="screen" rel="stylesheet">', rendered)
|
||||
|
||||
# Command to load the JS from Media.js
|
||||
self.assertIn(
|
||||
"Components.unescapeJs(\\`&lt;script js_tag src=&quot;path/to/script.js&quot; type=&quot;module&quot;&gt;&lt;/script&gt;\\`)",
|
||||
rendered,
|
||||
)
|
||||
self.assertIn(
|
||||
"Components.unescapeJs(\\`&lt;script hi src=&quot;path/to/script2.js&quot;&gt;&lt;/script&gt;\\`)",
|
||||
rendered,
|
||||
)
|
||||
self.assertIn(
|
||||
"Components.unescapeJs(\\`&lt;script type=&quot;module&quot; src=&quot;path/to/script3.js&quot;&gt;&lt;/script&gt;\\`)",
|
||||
rendered,
|
||||
)
|
||||
self.assertIn(
|
||||
"Components.unescapeJs(\\`&lt;script src=&quot;path/to/script4.js&quot;&gt;&lt;/script&gt;\\`)",
|
||||
rendered,
|
||||
)
|
||||
self.assertInHTML('<script js_tag src="path/to/script.js" type="module"></script>', rendered)
|
||||
self.assertInHTML('<script hi src="path/to/script2.js"></script>', rendered)
|
||||
self.assertInHTML('<script type="module" src="path/to/script3.js"></script>', rendered)
|
||||
self.assertInHTML('<script src="path/to/script4.js"></script>', rendered)
|
||||
|
||||
def test_pathlike(self):
|
||||
"""
|
||||
|
@ -376,19 +343,9 @@ class MediaPathAsObjectTests(BaseTestCase):
|
|||
self.assertInHTML('<link href="path/to/style3.css" media="print" rel="stylesheet">', rendered)
|
||||
self.assertInHTML('<link href="path/to/style4.css" media="screen" rel="stylesheet">', rendered)
|
||||
|
||||
# Command to load the JS from Media.js
|
||||
self.assertIn(
|
||||
"Components.unescapeJs(\\`&lt;script src=&quot;path/to/script.js&quot;&gt;&lt;/script&gt;\\`)",
|
||||
rendered,
|
||||
)
|
||||
self.assertIn(
|
||||
"Components.unescapeJs(\\`&lt;script src=&quot;path/to/script2.js&quot;&gt;&lt;/script&gt;\\`)",
|
||||
rendered,
|
||||
)
|
||||
self.assertIn(
|
||||
"Components.unescapeJs(\\`&lt;script src=&quot;path/to/script3.js&quot;&gt;&lt;/script&gt;\\`)",
|
||||
rendered,
|
||||
)
|
||||
self.assertInHTML('<script src="path/to/script.js"></script>', rendered)
|
||||
self.assertInHTML('<script src="path/to/script2.js"></script>', rendered)
|
||||
self.assertInHTML('<script src="path/to/script3.js"></script>', rendered)
|
||||
|
||||
def test_str(self):
|
||||
"""
|
||||
|
@ -429,15 +386,8 @@ class MediaPathAsObjectTests(BaseTestCase):
|
|||
self.assertInHTML('<link href="path/to/style3.css" media="print" rel="stylesheet">', rendered)
|
||||
self.assertInHTML('<link href="path/to/style4.css" media="screen" rel="stylesheet">', rendered)
|
||||
|
||||
# Command to load the JS from Media.js
|
||||
self.assertIn(
|
||||
"Components.unescapeJs(\\`&lt;script src=&quot;path/to/script.js&quot;&gt;&lt;/script&gt;\\`)",
|
||||
rendered,
|
||||
)
|
||||
self.assertIn(
|
||||
"Components.unescapeJs(\\`&lt;script src=&quot;path/to/script2.js&quot;&gt;&lt;/script&gt;\\`)",
|
||||
rendered,
|
||||
)
|
||||
self.assertInHTML('<script src="path/to/script.js"></script>', rendered)
|
||||
self.assertInHTML('<script src="path/to/script2.js"></script>', rendered)
|
||||
|
||||
def test_bytes(self):
|
||||
"""
|
||||
|
@ -478,15 +428,8 @@ class MediaPathAsObjectTests(BaseTestCase):
|
|||
self.assertInHTML('<link href="path/to/style3.css" media="print" rel="stylesheet">', rendered)
|
||||
self.assertInHTML('<link href="path/to/style4.css" media="screen" rel="stylesheet">', rendered)
|
||||
|
||||
# Command to load the JS from Media.js
|
||||
self.assertIn(
|
||||
"Components.unescapeJs(\\`&lt;script src=&quot;path/to/script.js&quot;&gt;&lt;/script&gt;\\`)",
|
||||
rendered,
|
||||
)
|
||||
self.assertIn(
|
||||
"Components.unescapeJs(\\`&lt;script src=&quot;path/to/script2.js&quot;&gt;&lt;/script&gt;\\`)",
|
||||
rendered,
|
||||
)
|
||||
self.assertInHTML('<script src="path/to/script.js"></script>', rendered)
|
||||
self.assertInHTML('<script src="path/to/script2.js"></script>', rendered)
|
||||
|
||||
def test_function(self):
|
||||
class SimpleComponent(Component):
|
||||
|
@ -517,23 +460,10 @@ class MediaPathAsObjectTests(BaseTestCase):
|
|||
self.assertInHTML('<link href="calendar/style2.css" media="all" rel="stylesheet">', rendered)
|
||||
self.assertInHTML('<link href="calendar/style3.css" media="all" rel="stylesheet">', rendered)
|
||||
|
||||
# Command to load the JS from Media.js
|
||||
self.assertIn(
|
||||
"Components.unescapeJs(\\`&lt;script hi src=&quot;calendar/script.js&quot;&gt;&lt;/script&gt;\\`)",
|
||||
rendered,
|
||||
)
|
||||
self.assertIn(
|
||||
"Components.unescapeJs(\\`&lt;script src=&quot;calendar/script1.js&quot;&gt;&lt;/script&gt;\\`)",
|
||||
rendered,
|
||||
)
|
||||
self.assertIn(
|
||||
"Components.unescapeJs(\\`&lt;script src=&quot;calendar/script2.js&quot;&gt;&lt;/script&gt;\\`)",
|
||||
rendered,
|
||||
)
|
||||
self.assertIn(
|
||||
"Components.unescapeJs(\\`&lt;script src=&quot;calendar/script3.js&quot;&gt;&lt;/script&gt;\\`)",
|
||||
rendered,
|
||||
)
|
||||
self.assertInHTML('<script hi src="calendar/script.js"></script>', rendered)
|
||||
self.assertInHTML('<script src="calendar/script1.js"></script>', rendered)
|
||||
self.assertInHTML('<script src="calendar/script2.js"></script>', rendered)
|
||||
self.assertInHTML('<script src="calendar/script3.js"></script>', rendered)
|
||||
|
||||
@override_settings(STATIC_URL="static/")
|
||||
def test_works_with_static(self):
|
||||
|
@ -570,23 +500,10 @@ class MediaPathAsObjectTests(BaseTestCase):
|
|||
self.assertInHTML('<link href="/static/calendar/style2.css" media="all" rel="stylesheet">', rendered)
|
||||
self.assertInHTML('<link href="/static/calendar/style3.css" media="all" rel="stylesheet">', rendered)
|
||||
|
||||
# Command to load the JS from Media.js
|
||||
self.assertIn(
|
||||
"Components.unescapeJs(\\`&lt;script hi src=&quot;/static/calendar/script.js&quot;&gt;&lt;/script&gt;\\`)",
|
||||
rendered,
|
||||
)
|
||||
self.assertIn(
|
||||
"Components.unescapeJs(\\`&lt;script src=&quot;/static/calendar/script1.js&quot;&gt;&lt;/script&gt;\\`)",
|
||||
rendered,
|
||||
)
|
||||
self.assertIn(
|
||||
"Components.unescapeJs(\\`&lt;script src=&quot;/static/calendar/script2.js&quot;&gt;&lt;/script&gt;\\`)",
|
||||
rendered,
|
||||
)
|
||||
self.assertIn(
|
||||
"Components.unescapeJs(\\`&lt;script src=&quot;/static/calendar/script3.js&quot;&gt;&lt;/script&gt;\\`)",
|
||||
rendered,
|
||||
)
|
||||
self.assertInHTML('<script hi src="/static/calendar/script.js"></script>', rendered)
|
||||
self.assertInHTML('<script src="/static/calendar/script1.js"></script>', rendered)
|
||||
self.assertInHTML('<script src="/static/calendar/script2.js"></script>', rendered)
|
||||
self.assertInHTML('<script src="/static/calendar/script3.js"></script>', rendered)
|
||||
|
||||
|
||||
class MediaStaticfilesTests(BaseTestCase):
|
||||
|
@ -634,11 +551,7 @@ class MediaStaticfilesTests(BaseTestCase):
|
|||
# be searched as specified above (e.g. `calendar/script.js`) inside `static_root` dir.
|
||||
self.assertInHTML('<link href="/static/calendar/style.css" media="all" rel="stylesheet">', rendered)
|
||||
|
||||
# Command to load the JS from Media.js
|
||||
self.assertIn(
|
||||
"Components.unescapeJs(\\`&lt;script defer src=&quot;/static/calendar/script.js&quot;&gt;&lt;/script&gt;\\`)",
|
||||
rendered,
|
||||
)
|
||||
self.assertInHTML('<script defer src="/static/calendar/script.js"></script>', rendered)
|
||||
|
||||
# For context see https://github.com/EmilStenstrom/django-components/issues/522
|
||||
@override_settings(
|
||||
|
@ -698,11 +611,7 @@ class MediaStaticfilesTests(BaseTestCase):
|
|||
'<link href="/static/calendar/style.0eeb72042b59.css" media="all" rel="stylesheet">', rendered
|
||||
)
|
||||
|
||||
# Command to load the JS from Media.js
|
||||
self.assertIn(
|
||||
"Components.unescapeJs(\\`&lt;script defer src=&quot;/static/calendar/script.e1815e23e0ec.js&quot;&gt;&lt;/script&gt;\\`)",
|
||||
rendered,
|
||||
)
|
||||
self.assertInHTML('<script defer src="/static/calendar/script.e1815e23e0ec.js"></script>', rendered)
|
||||
|
||||
|
||||
class MediaRelativePathTests(BaseTestCase):
|
||||
|
@ -790,11 +699,7 @@ class MediaRelativePathTests(BaseTestCase):
|
|||
rendered,
|
||||
)
|
||||
|
||||
# Command to load the JS from Media.js
|
||||
self.assertIn(
|
||||
"Components.unescapeJs(\\`&lt;link href=&quot;relative_file/relative_file.css&quot; media=&quot;all&quot; rel=&quot;stylesheet&quot;&gt;\\`)",
|
||||
rendered,
|
||||
)
|
||||
self.assertInHTML('<link href="relative_file/relative_file.css" media="all" rel="stylesheet">', rendered)
|
||||
|
||||
# Settings required for autodiscover to work
|
||||
@override_settings(
|
||||
|
@ -863,8 +768,4 @@ class MediaRelativePathTests(BaseTestCase):
|
|||
self.assertInHTML('<input type="text" name="variable" value="abc">', rendered)
|
||||
self.assertInHTML('<link href="relative_file_pathobj.css" rel="stylesheet">', rendered)
|
||||
|
||||
# Command to load the JS from Media.js
|
||||
self.assertIn(
|
||||
"Components.unescapeJs(\\`&lt;script type=&quot;module&quot; src=&quot;relative_file_pathobj.js&quot;&gt;&lt;/script&gt;\\`)",
|
||||
rendered,
|
||||
)
|
||||
self.assertInHTML('<script type="module" src="relative_file_pathobj.js"></script>', rendered)
|
||||
|
|
|
@ -208,7 +208,7 @@ class RenderDependenciesTests(BaseTestCase):
|
|||
rendered_raw = Template(template_str).render(Context({}))
|
||||
rendered = render_dependencies(rendered_raw)
|
||||
|
||||
self.assertEqual(rendered.count("<script"), 3)
|
||||
self.assertEqual(rendered.count("<script"), 4)
|
||||
self.assertEqual(rendered.count("<style"), 1)
|
||||
self.assertEqual(rendered.count("<link"), 1)
|
||||
self.assertEqual(rendered.count("_RENDERED"), 0)
|
||||
|
@ -256,7 +256,7 @@ class RenderDependenciesTests(BaseTestCase):
|
|||
rendered_raw = Template(template_str).render(Context({}))
|
||||
rendered = render_dependencies(rendered_raw)
|
||||
|
||||
self.assertEqual(rendered.count("<script"), 3)
|
||||
self.assertEqual(rendered.count("<script"), 4)
|
||||
self.assertEqual(rendered.count("<style"), 1)
|
||||
self.assertEqual(rendered.count("<link"), 1)
|
||||
self.assertEqual(rendered.count("_RENDERED"), 0)
|
||||
|
|
|
@ -61,13 +61,22 @@ class DependencyManagerTests(_BaseDepManagerTestCase):
|
|||
|
||||
keys = await page.evaluate("Object.keys(Components.manager)")
|
||||
self.assertEqual(
|
||||
keys, ["callComponent", "registerComponent", "registerComponentData", "loadScript", "markScriptLoaded"]
|
||||
keys,
|
||||
[
|
||||
"callComponent",
|
||||
"registerComponent",
|
||||
"registerComponentData",
|
||||
"loadJs",
|
||||
"loadCss",
|
||||
"markScriptLoaded",
|
||||
"_loadComponentScripts",
|
||||
],
|
||||
)
|
||||
|
||||
await page.close()
|
||||
|
||||
|
||||
# Tests for `manager.loadScript()` / `manager.markAsLoaded()`
|
||||
# Tests for `manager.loadJs()` / `manager.loadCss()` / `manager.markAsLoaded()`
|
||||
@override_settings(STATIC_URL="static/")
|
||||
class LoadScriptTests(_BaseDepManagerTestCase):
|
||||
@with_playwright
|
||||
|
@ -81,15 +90,15 @@ class LoadScriptTests(_BaseDepManagerTestCase):
|
|||
const headBeforeFirstLoad = document.head.innerHTML;
|
||||
|
||||
// Adds a script the first time
|
||||
manager.loadScript('js', "<script src='/one/two'></script>");
|
||||
manager.loadJs("<script src='/one/two'></script>");
|
||||
const bodyAfterFirstLoad = document.body.innerHTML;
|
||||
|
||||
// Does not add it the second time
|
||||
manager.loadScript('js', "<script src='/one/two'></script>");
|
||||
manager.loadJs("<script src='/one/two'></script>");
|
||||
const bodyAfterSecondLoad = document.body.innerHTML;
|
||||
|
||||
// Adds different script
|
||||
manager.loadScript('js', "<script src='/four/three'></script>");
|
||||
manager.loadJs("<script src='/four/three'></script>");
|
||||
const bodyAfterThirdLoad = document.body.innerHTML;
|
||||
|
||||
const headAfterThirdLoad = document.head.innerHTML;
|
||||
|
@ -127,15 +136,15 @@ class LoadScriptTests(_BaseDepManagerTestCase):
|
|||
const bodyBeforeFirstLoad = document.body.innerHTML;
|
||||
|
||||
// Adds a script the first time
|
||||
manager.loadScript('css', "<link href='/one/two'>");
|
||||
manager.loadCss("<link href='/one/two'>");
|
||||
const headAfterFirstLoad = document.head.innerHTML;
|
||||
|
||||
// Does not add it the second time
|
||||
manager.loadScript('css', "<link herf='/one/two'>");
|
||||
manager.loadCss("<link herf='/one/two'>");
|
||||
const headAfterSecondLoad = document.head.innerHTML;
|
||||
|
||||
// Adds different script
|
||||
manager.loadScript('css', "<link href='/four/three'>");
|
||||
manager.loadCss("<link href='/four/three'>");
|
||||
const headAfterThirdLoad = document.head.innerHTML;
|
||||
|
||||
const bodyAfterThirdLoad = document.body.innerHTML;
|
||||
|
@ -172,10 +181,10 @@ class LoadScriptTests(_BaseDepManagerTestCase):
|
|||
manager.markScriptLoaded('css', '/one/two');
|
||||
manager.markScriptLoaded('js', '/one/three');
|
||||
|
||||
manager.loadScript('css', "<link href='/one/two'>");
|
||||
manager.loadCss("<link href='/one/two'>");
|
||||
const headAfterFirstLoad = document.head.innerHTML;
|
||||
|
||||
manager.loadScript('js', "<script src='/one/three'></script>");
|
||||
manager.loadJs("<script src='/one/three'></script>");
|
||||
const bodyAfterSecondLoad = document.body.innerHTML;
|
||||
|
||||
return {
|
||||
|
|
|
@ -127,10 +127,19 @@ class DependencyRenderingTests(BaseTestCase):
|
|||
self.assertEqual(rendered.count("<link"), 0) # No CSS
|
||||
self.assertEqual(rendered.count("<style"), 0)
|
||||
|
||||
self.assertEqual(rendered.count("const loadedJsScripts = [];"), 1)
|
||||
self.assertEqual(rendered.count("const loadedCssScripts = [];"), 1)
|
||||
self.assertEqual(rendered.count(r"const toLoadJsScripts = [];"), 1)
|
||||
self.assertEqual(rendered.count(r"const toLoadCssScripts = [];"), 1)
|
||||
# We expect to find this:
|
||||
# ```js
|
||||
# Components.manager._loadComponentScripts({
|
||||
# loadedCssUrls: [],
|
||||
# loadedJsUrls: [],
|
||||
# toLoadCssTags: [],
|
||||
# toLoadJsTags: [],
|
||||
# });
|
||||
# ```
|
||||
self.assertEqual(rendered.count("loadedJsUrls: [],"), 1)
|
||||
self.assertEqual(rendered.count("loadedCssUrls: [],"), 1)
|
||||
self.assertEqual(rendered.count("toLoadJsTags: [],"), 1)
|
||||
self.assertEqual(rendered.count("toLoadCssTags: [],"), 1)
|
||||
|
||||
def test_no_js_dependencies_when_no_components_used(self):
|
||||
registry.register(name="test", component=SimpleComponent)
|
||||
|
@ -148,10 +157,19 @@ class DependencyRenderingTests(BaseTestCase):
|
|||
self.assertEqual(rendered.count("<link"), 0) # No CSS
|
||||
self.assertEqual(rendered.count("<style"), 0)
|
||||
|
||||
self.assertEqual(rendered.count("const loadedJsScripts = [];"), 1)
|
||||
self.assertEqual(rendered.count("const loadedCssScripts = [];"), 1)
|
||||
self.assertEqual(rendered.count(r"const toLoadJsScripts = [];"), 1)
|
||||
self.assertEqual(rendered.count(r"const toLoadCssScripts = [];"), 1)
|
||||
# We expect to find this:
|
||||
# ```js
|
||||
# Components.manager._loadComponentScripts({
|
||||
# loadedCssUrls: [],
|
||||
# loadedJsUrls: [],
|
||||
# toLoadCssTags: [],
|
||||
# toLoadJsTags: [],
|
||||
# });
|
||||
# ```
|
||||
self.assertEqual(rendered.count("loadedJsUrls: [],"), 1)
|
||||
self.assertEqual(rendered.count("loadedCssUrls: [],"), 1)
|
||||
self.assertEqual(rendered.count("toLoadJsTags: [],"), 1)
|
||||
self.assertEqual(rendered.count("toLoadCssTags: [],"), 1)
|
||||
|
||||
def test_no_css_dependencies_when_no_components_used(self):
|
||||
registry.register(name="test", component=SimpleComponent)
|
||||
|
@ -184,22 +202,21 @@ class DependencyRenderingTests(BaseTestCase):
|
|||
self.assertEqual(rendered.count('<link href="style.css" media="all" rel="stylesheet">'), 1) # Media.css
|
||||
self.assertEqual(rendered.count("<link"), 1)
|
||||
self.assertEqual(rendered.count("<style"), 0)
|
||||
self.assertEqual(rendered.count("<script"), 2)
|
||||
self.assertEqual(rendered.count("<script"), 3)
|
||||
|
||||
self.assertEqual(rendered.count("const loadedJsScripts = [];"), 1)
|
||||
self.assertEqual(rendered.count("const loadedCssScripts = ["style.css"];"), 1)
|
||||
self.assertEqual(
|
||||
rendered.count(
|
||||
r"const toLoadJsScripts = [Components.unescapeJs(\`&lt;script src=&quot;script.js&quot;&gt;&lt;/script&gt;\`)];"
|
||||
),
|
||||
1,
|
||||
)
|
||||
self.assertEqual(
|
||||
rendered.count(
|
||||
r"const toLoadCssScripts = [Components.unescapeJs(\`&lt;link href=&quot;style.css&quot; media=&quot;all&quot; rel=&quot;stylesheet&quot;&gt;\`)];"
|
||||
),
|
||||
1,
|
||||
)
|
||||
# We expect to find this:
|
||||
# ```js
|
||||
# Components.manager._loadComponentScripts({
|
||||
# loadedCssUrls: ["style.css"],
|
||||
# loadedJsUrls: ["script.js"],
|
||||
# toLoadCssTags: [],
|
||||
# toLoadJsTags: [],
|
||||
# });
|
||||
# ```
|
||||
self.assertEqual(rendered.count("loadedJsUrls: ["script.js"],"), 1)
|
||||
self.assertEqual(rendered.count("loadedCssUrls: ["style.css"],"), 1)
|
||||
self.assertEqual(rendered.count("toLoadJsTags: [],"), 1)
|
||||
self.assertEqual(rendered.count("toLoadCssTags: [],"), 1)
|
||||
|
||||
def test_single_component_with_dash_or_slash_in_name(self):
|
||||
registry.register(name="te-s/t", component=SimpleComponent)
|
||||
|
@ -219,22 +236,21 @@ class DependencyRenderingTests(BaseTestCase):
|
|||
self.assertEqual(rendered.count('<link href="style.css" media="all" rel="stylesheet">'), 1) # Media.css
|
||||
self.assertEqual(rendered.count("<link"), 1)
|
||||
self.assertEqual(rendered.count("<style"), 0)
|
||||
self.assertEqual(rendered.count("<script"), 2)
|
||||
self.assertEqual(rendered.count("<script"), 3)
|
||||
|
||||
self.assertEqual(rendered.count("const loadedJsScripts = [];"), 1)
|
||||
self.assertEqual(rendered.count("const loadedCssScripts = ["style.css"];"), 1)
|
||||
self.assertEqual(
|
||||
rendered.count(
|
||||
r"const toLoadJsScripts = [Components.unescapeJs(\`&lt;script src=&quot;script.js&quot;&gt;&lt;/script&gt;\`)];"
|
||||
),
|
||||
1,
|
||||
)
|
||||
self.assertEqual(
|
||||
rendered.count(
|
||||
r"const toLoadCssScripts = [Components.unescapeJs(\`&lt;link href=&quot;style.css&quot; media=&quot;all&quot; rel=&quot;stylesheet&quot;&gt;\`)];"
|
||||
),
|
||||
1,
|
||||
)
|
||||
# We expect to find this:
|
||||
# ```js
|
||||
# Components.manager._loadComponentScripts({
|
||||
# loadedCssUrls: ["style.css"],
|
||||
# loadedJsUrls: ["script.js"],
|
||||
# toLoadCssTags: [],
|
||||
# toLoadJsTags: [],
|
||||
# });
|
||||
# ```
|
||||
self.assertEqual(rendered.count("loadedJsUrls: ["script.js"],"), 1)
|
||||
self.assertEqual(rendered.count("loadedCssUrls: ["style.css"],"), 1)
|
||||
self.assertEqual(rendered.count("toLoadJsTags: [],"), 1)
|
||||
self.assertEqual(rendered.count("toLoadCssTags: [],"), 1)
|
||||
|
||||
def test_single_component_placeholder_removed(self):
|
||||
registry.register(name="test", component=SimpleComponent)
|
||||
|
@ -285,22 +301,21 @@ class DependencyRenderingTests(BaseTestCase):
|
|||
# CSS NOT included
|
||||
self.assertEqual(rendered.count("<link"), 0)
|
||||
self.assertEqual(rendered.count("<style"), 0)
|
||||
self.assertEqual(rendered.count("<script"), 2)
|
||||
self.assertEqual(rendered.count("<script"), 3)
|
||||
|
||||
self.assertEqual(rendered.count("const loadedJsScripts = [];"), 1)
|
||||
self.assertEqual(rendered.count("const loadedCssScripts = ["style.css"];"), 1)
|
||||
self.assertEqual(
|
||||
rendered.count(
|
||||
r"const toLoadJsScripts = [Components.unescapeJs(\`&lt;script src=&quot;script.js&quot;&gt;&lt;/script&gt;\`)];"
|
||||
),
|
||||
1,
|
||||
)
|
||||
self.assertEqual(
|
||||
rendered.count(
|
||||
r"const toLoadCssScripts = [Components.unescapeJs(\`&lt;link href=&quot;style.css&quot; media=&quot;all&quot; rel=&quot;stylesheet&quot;&gt;\`)];"
|
||||
),
|
||||
1,
|
||||
)
|
||||
# We expect to find this:
|
||||
# ```js
|
||||
# Components.manager._loadComponentScripts({
|
||||
# loadedCssUrls: ["style.css"],
|
||||
# loadedJsUrls: ["script.js"],
|
||||
# toLoadCssTags: [],
|
||||
# toLoadJsTags: [],
|
||||
# });
|
||||
# ```
|
||||
self.assertEqual(rendered.count("loadedJsUrls: ["script.js"],"), 1)
|
||||
self.assertEqual(rendered.count("loadedCssUrls: ["style.css"],"), 1)
|
||||
self.assertEqual(rendered.count("toLoadJsTags: [],"), 1)
|
||||
self.assertEqual(rendered.count("toLoadCssTags: [],"), 1)
|
||||
|
||||
def test_all_dependencies_are_rendered_for_component_with_multiple_dependencies(
|
||||
self,
|
||||
|
@ -320,31 +335,41 @@ class DependencyRenderingTests(BaseTestCase):
|
|||
|
||||
self.assertEqual(rendered.count("<link"), 2)
|
||||
self.assertEqual(rendered.count("<style"), 0)
|
||||
self.assertEqual(rendered.count("<script"), 2) # Boilerplate scripts
|
||||
self.assertEqual(rendered.count("<script"), 4) # 2 scripts belong to the boilerplate
|
||||
|
||||
self.assertEqual(rendered.count('<link href="style.css" media="all" rel="stylesheet">'), 1) # Media.css
|
||||
self.assertEqual(rendered.count('<link href="style2.css" media="all" rel="stylesheet">'), 1)
|
||||
|
||||
self.assertEqual(rendered.count("const loadedJsScripts = [];"), 1)
|
||||
self.assertEqual(
|
||||
rendered.count("const loadedCssScripts = ["style.css", "style2.css"];"), 1
|
||||
# Media.css
|
||||
self.assertInHTML(
|
||||
"""
|
||||
<link href="style.css" media="all" rel="stylesheet">
|
||||
<link href="style2.css" media="all" rel="stylesheet">
|
||||
""",
|
||||
rendered,
|
||||
count=1,
|
||||
)
|
||||
|
||||
# JS ORDER - "script.js", "script2.js"
|
||||
self.assertEqual(
|
||||
rendered.count(
|
||||
r"const toLoadJsScripts = [Components.unescapeJs(\`&lt;script src=&quot;script.js&quot;&gt;&lt;/script&gt;\`), Components.unescapeJs(\`&lt;script src=&quot;script2.js&quot;&gt;&lt;/script&gt;\`)];"
|
||||
),
|
||||
1,
|
||||
# Media.js
|
||||
self.assertInHTML(
|
||||
"""
|
||||
<script src="script.js"></script>
|
||||
<script src="script2.js"></script>
|
||||
""",
|
||||
rendered,
|
||||
count=1,
|
||||
)
|
||||
|
||||
# CSS ORDER - "style.css", "style2.css"
|
||||
self.assertEqual(
|
||||
rendered.count(
|
||||
r"const toLoadCssScripts = [Components.unescapeJs(\`&lt;link href=&quot;style.css&quot; media=&quot;all&quot; rel=&quot;stylesheet&quot;&gt;\`), Components.unescapeJs(\`&lt;link href=&quot;style2.css&quot; media=&quot;all&quot; rel=&quot;stylesheet&quot;&gt;\`)];"
|
||||
),
|
||||
1,
|
||||
)
|
||||
# We expect to find this:
|
||||
# ```js
|
||||
# Components.manager._loadComponentScripts({
|
||||
# loadedCssUrls: ["style.css", "style2.css"],
|
||||
# loadedJsUrls: ["script.js", "script2.js"],
|
||||
# toLoadCssTags: [],
|
||||
# toLoadJsTags: [],
|
||||
# });
|
||||
# ```
|
||||
self.assertEqual(rendered.count("loadedCssUrls: ["style.css", "style2.css"],"), 1)
|
||||
self.assertEqual(rendered.count("loadedJsUrls: ["script.js", "script2.js""), 1)
|
||||
self.assertEqual(rendered.count("toLoadCssTags: [],"), 1)
|
||||
self.assertEqual(rendered.count("toLoadJsTags: [],"), 1)
|
||||
|
||||
def test_no_dependencies_with_multiple_unused_components(self):
|
||||
registry.register(name="inner", component=SimpleComponent)
|
||||
|
@ -361,14 +386,23 @@ class DependencyRenderingTests(BaseTestCase):
|
|||
# Dependency manager script
|
||||
self.assertInHTML('<script src="django_components/django_components.min.js"></script>', rendered, count=1)
|
||||
|
||||
self.assertEqual(rendered.count("<script"), 2) # Two 2 scripts belong to the boilerplate
|
||||
self.assertEqual(rendered.count("<script"), 2) # 2 scripts belong to the boilerplate
|
||||
self.assertEqual(rendered.count("<link"), 0) # No CSS
|
||||
self.assertEqual(rendered.count("<style"), 0)
|
||||
|
||||
self.assertEqual(rendered.count("const loadedJsScripts = [];"), 1)
|
||||
self.assertEqual(rendered.count("const loadedCssScripts = [];"), 1)
|
||||
self.assertEqual(rendered.count("const toLoadJsScripts = [];"), 1)
|
||||
self.assertEqual(rendered.count("const toLoadCssScripts = [];"), 1)
|
||||
# We expect to find this:
|
||||
# ```js
|
||||
# Components.manager._loadComponentScripts({
|
||||
# loadedCssUrls: [],
|
||||
# loadedJsUrls: [],
|
||||
# toLoadCssTags: [],
|
||||
# toLoadJsTags: [],
|
||||
# });
|
||||
# ```
|
||||
self.assertEqual(rendered.count("loadedJsUrls: [],"), 1)
|
||||
self.assertEqual(rendered.count("loadedCssUrls: [],"), 1)
|
||||
self.assertEqual(rendered.count("toLoadJsTags: [],"), 1)
|
||||
self.assertEqual(rendered.count("toLoadCssTags: [],"), 1)
|
||||
|
||||
def test_multiple_components_dependencies(self):
|
||||
registry.register(name="inner", component=SimpleComponent)
|
||||
|
@ -390,55 +424,76 @@ class DependencyRenderingTests(BaseTestCase):
|
|||
# NOTE: Should be present only ONCE!
|
||||
self.assertInHTML('<script src="django_components/django_components.min.js"></script>', rendered, count=1)
|
||||
|
||||
self.assertEqual(rendered.count("<script"), 4) # Two 2 scripts belong to the boilerplate
|
||||
self.assertEqual(rendered.count("<script"), 7) # 2 scripts belong to the boilerplate
|
||||
self.assertEqual(rendered.count("<link"), 3)
|
||||
self.assertEqual(rendered.count("<style"), 2)
|
||||
|
||||
# Components' inlined CSS
|
||||
# NOTE: Each of these should be present only ONCE!
|
||||
self.assertInHTML("<style>.xyz { color: red; }</style>", rendered, count=1)
|
||||
self.assertInHTML("<style>.my-class { color: red; }</style>", rendered, count=1)
|
||||
self.assertInHTML(
|
||||
"""
|
||||
<style>.my-class { color: red; }</style>
|
||||
<style>.xyz { color: red; }</style>
|
||||
""",
|
||||
rendered,
|
||||
count=1,
|
||||
)
|
||||
|
||||
# Components' Media.css
|
||||
# NOTE: Each of these should be present only ONCE!
|
||||
self.assertInHTML('<link href="xyz1.css" media="all" rel="stylesheet">', rendered, count=1)
|
||||
self.assertInHTML('<link href="style.css" media="all" rel="stylesheet">', rendered, count=1)
|
||||
self.assertInHTML('<link href="style2.css" media="all" rel="stylesheet">', rendered, count=1)
|
||||
|
||||
self.assertEqual(
|
||||
rendered.count(
|
||||
"const loadedJsScripts = ["/components/cache/OtherComponent_6329ae.js/", "/components/cache/SimpleComponentNested_f02d32.js/"];"
|
||||
),
|
||||
1,
|
||||
)
|
||||
self.assertEqual(
|
||||
rendered.count(
|
||||
"const loadedCssScripts = ["/components/cache/OtherComponent_6329ae.css/", "/components/cache/SimpleComponentNested_f02d32.css/", "style.css", "style2.css", "xyz1.css"];"
|
||||
),
|
||||
1,
|
||||
)
|
||||
|
||||
# JS ORDER:
|
||||
# - "script2.js" (from SimpleComponentNested)
|
||||
# - "script.js" (from SimpleComponent inside SimpleComponentNested)
|
||||
# - "xyz1.js" (from OtherComponent inserted into SimpleComponentNested)
|
||||
self.assertEqual(
|
||||
rendered.count(
|
||||
r"const toLoadJsScripts = [Components.unescapeJs(\`&lt;script src=&quot;script2.js&quot;&gt;&lt;/script&gt;\`), Components.unescapeJs(\`&lt;script src=&quot;script.js&quot;&gt;&lt;/script&gt;\`), Components.unescapeJs(\`&lt;script src=&quot;xyz1.js&quot;&gt;&lt;/script&gt;\`)];"
|
||||
),
|
||||
1,
|
||||
)
|
||||
|
||||
# CSS ORDER:
|
||||
# Order:
|
||||
# - "style.css", "style2.css" (from SimpleComponentNested)
|
||||
# - "style.css" (from SimpleComponent inside SimpleComponentNested)
|
||||
# - "xyz1.css" (from OtherComponent inserted into SimpleComponentNested)
|
||||
self.assertInHTML(
|
||||
"""
|
||||
<link href="style.css" media="all" rel="stylesheet">
|
||||
<link href="style2.css" media="all" rel="stylesheet">
|
||||
<link href="xyz1.css" media="all" rel="stylesheet">
|
||||
""",
|
||||
rendered,
|
||||
count=1,
|
||||
)
|
||||
|
||||
# Components' Media.js followed by inlined JS
|
||||
# Order:
|
||||
# - "script2.js" (from SimpleComponentNested)
|
||||
# - "script.js" (from SimpleComponent inside SimpleComponentNested)
|
||||
# - "xyz1.js" (from OtherComponent inserted into SimpleComponentNested)
|
||||
self.assertInHTML(
|
||||
"""
|
||||
<script src="script2.js"></script>
|
||||
<script src="script.js"></script>
|
||||
<script src="xyz1.js"></script>
|
||||
<script>eval(Components.unescapeJs(`console.log("Hello");`))</script>
|
||||
<script>eval(Components.unescapeJs(`console.log("xyz");`))</script>
|
||||
""",
|
||||
rendered,
|
||||
count=1,
|
||||
)
|
||||
|
||||
# We expect to find this:
|
||||
# ```js
|
||||
# Components.manager._loadComponentScripts({
|
||||
# loadedCssUrls: ["/components/cache/OtherComponent_6329ae.css/", "/components/cache/SimpleComponentNested_f02d32.css/", "style.css", "style2.css", "xyz1.css"],
|
||||
# loadedJsUrls: ["/components/cache/OtherComponent_6329ae.js/", "/components/cache/SimpleComponentNested_f02d32.js/", "script.js", "script2.js", "xyz1.js"],
|
||||
# toLoadCssTags: [],
|
||||
# toLoadJsTags: [],
|
||||
# });
|
||||
# ```
|
||||
self.assertEqual(
|
||||
rendered.count(
|
||||
r"const toLoadCssScripts = [Components.unescapeJs(\`&lt;link href=&quot;style.css&quot; media=&quot;all&quot; rel=&quot;stylesheet&quot;&gt;\`), Components.unescapeJs(\`&lt;link href=&quot;style2.css&quot; media=&quot;all&quot; rel=&quot;stylesheet&quot;&gt;\`), Components.unescapeJs(\`&lt;link href=&quot;xyz1.css&quot; media=&quot;all&quot; rel=&quot;stylesheet&quot;&gt;\`)];"
|
||||
"loadedJsUrls: ["/components/cache/OtherComponent_6329ae.js/", "/components/cache/SimpleComponentNested_f02d32.js/", "script.js", "script2.js", "xyz1.js"],"
|
||||
),
|
||||
1,
|
||||
)
|
||||
self.assertEqual(
|
||||
rendered.count(
|
||||
"loadedCssUrls: ["/components/cache/OtherComponent_6329ae.css/", "/components/cache/SimpleComponentNested_f02d32.css/", "style.css", "style2.css", "xyz1.css"],"
|
||||
),
|
||||
1,
|
||||
)
|
||||
self.assertEqual(rendered.count("toLoadJsTags: [],"), 1)
|
||||
self.assertEqual(rendered.count("toLoadCssTags: [],"), 1)
|
||||
|
||||
def test_multiple_components_all_placeholders_removed(self):
|
||||
registry.register(name="inner", component=SimpleComponent)
|
||||
|
|
|
@ -215,3 +215,132 @@ class E2eDependencyRenderingTests(BaseTestCase):
|
|||
self.assertEqual("rgb(255, 0, 0)", data["myStyle2Color"]) # AKA 'color: red'
|
||||
|
||||
await page.close()
|
||||
|
||||
@with_playwright
|
||||
async def test_js_executed_in_order__js(self):
|
||||
single_comp_url = TEST_SERVER_URL + "/js-order/js"
|
||||
|
||||
page: Page = await self.browser.new_page()
|
||||
await page.goto(single_comp_url)
|
||||
|
||||
test_js: types.js = """() => {
|
||||
// NOTE: This variable should be defined by `check_script_order` component,
|
||||
// and it should contain all other variables defined by the previous components
|
||||
return checkVars;
|
||||
}"""
|
||||
|
||||
data = await page.evaluate(test_js)
|
||||
|
||||
# Check components' inlined JS got loaded
|
||||
self.assertEqual(data["testSimpleComponent"], "kapowww!")
|
||||
self.assertEqual(data["testSimpleComponentNested"], "bongo!")
|
||||
self.assertEqual(data["testOtherComponent"], "wowzee!")
|
||||
|
||||
# Check JS from Media.js got loaded
|
||||
self.assertEqual(data["testMsg"], {"hello": "world"})
|
||||
self.assertEqual(data["testMsg2"], {"hello2": "world2"})
|
||||
|
||||
await page.close()
|
||||
|
||||
@with_playwright
|
||||
async def test_js_executed_in_order__media(self):
|
||||
single_comp_url = TEST_SERVER_URL + "/js-order/media"
|
||||
|
||||
page: Page = await self.browser.new_page()
|
||||
await page.goto(single_comp_url)
|
||||
|
||||
test_js: types.js = """() => {
|
||||
// NOTE: This variable should be defined by `check_script_order` component,
|
||||
// and it should contain all other variables defined by the previous components
|
||||
return checkVars;
|
||||
}"""
|
||||
|
||||
data = await page.evaluate(test_js)
|
||||
|
||||
# Check components' inlined JS got loaded
|
||||
# NOTE: The Media JS are loaded BEFORE the components' JS, so they should be empty
|
||||
self.assertEqual(data["testSimpleComponent"], None)
|
||||
self.assertEqual(data["testSimpleComponentNested"], None)
|
||||
self.assertEqual(data["testOtherComponent"], None)
|
||||
|
||||
# Check JS from Media.js
|
||||
self.assertEqual(data["testMsg"], {"hello": "world"})
|
||||
self.assertEqual(data["testMsg2"], {"hello2": "world2"})
|
||||
|
||||
await page.close()
|
||||
|
||||
# In this case the component whose JS is accessing data from other components
|
||||
# is used in the template before the other components. So the JS should
|
||||
# not be able to access the data from the other components.
|
||||
@with_playwright
|
||||
async def test_js_executed_in_order__invalid(self):
|
||||
single_comp_url = TEST_SERVER_URL + "/js-order/invalid"
|
||||
|
||||
page: Page = await self.browser.new_page()
|
||||
await page.goto(single_comp_url)
|
||||
|
||||
test_js: types.js = """() => {
|
||||
// checkVars was defined BEFORE other components, so it should be empty!
|
||||
return checkVars;
|
||||
}"""
|
||||
|
||||
data = await page.evaluate(test_js)
|
||||
|
||||
# Check components' inlined JS got loaded
|
||||
self.assertEqual(data["testSimpleComponent"], None)
|
||||
self.assertEqual(data["testSimpleComponentNested"], None)
|
||||
self.assertEqual(data["testOtherComponent"], None)
|
||||
|
||||
# Check JS from Media.js got loaded
|
||||
self.assertEqual(data["testMsg"], None)
|
||||
self.assertEqual(data["testMsg2"], None)
|
||||
|
||||
await page.close()
|
||||
|
||||
@with_playwright
|
||||
async def test_alpine__head(self):
|
||||
single_comp_url = TEST_SERVER_URL + "/alpine/head"
|
||||
|
||||
page: Page = await self.browser.new_page()
|
||||
await page.goto(single_comp_url)
|
||||
|
||||
component_text = await page.locator('[x-data="alpine_test"]').text_content()
|
||||
self.assertHTMLEqual(component_text.strip(), "ALPINE_TEST: 123")
|
||||
|
||||
await page.close()
|
||||
|
||||
@with_playwright
|
||||
async def test_alpine__body(self):
|
||||
single_comp_url = TEST_SERVER_URL + "/alpine/body"
|
||||
|
||||
page: Page = await self.browser.new_page()
|
||||
await page.goto(single_comp_url)
|
||||
|
||||
component_text = await page.locator('[x-data="alpine_test"]').text_content()
|
||||
self.assertHTMLEqual(component_text.strip(), "ALPINE_TEST: 123")
|
||||
|
||||
await page.close()
|
||||
|
||||
@with_playwright
|
||||
async def test_alpine__body2(self):
|
||||
single_comp_url = TEST_SERVER_URL + "/alpine/body2"
|
||||
|
||||
page: Page = await self.browser.new_page()
|
||||
await page.goto(single_comp_url)
|
||||
|
||||
component_text = await page.locator('[x-data="alpine_test"]').text_content()
|
||||
self.assertHTMLEqual(component_text.strip(), "ALPINE_TEST: 123")
|
||||
|
||||
await page.close()
|
||||
|
||||
@with_playwright
|
||||
async def test_alpine__invalid(self):
|
||||
single_comp_url = TEST_SERVER_URL + "/alpine/invalid"
|
||||
|
||||
page: Page = await self.browser.new_page()
|
||||
await page.goto(single_comp_url)
|
||||
|
||||
component_text = await page.locator('[x-data="alpine_test"]').text_content()
|
||||
self.assertHTMLEqual(component_text.strip(), "ALPINE_TEST:")
|
||||
|
||||
await page.close()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue