Skip to content

Commit cfebe38

Browse files
authored
Merge pull request #1255 from plotly/reload-window
hard reload targets just this window
2 parents ebac7d4 + 3309c81 commit cfebe38

File tree

5 files changed

+57
-12
lines changed

5 files changed

+57
-12
lines changed

Diff for: CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
1010
- [#1237](https://github.com/plotly/dash/pull/1237) Closes [#920](https://github.com/plotly/dash/issues/920): Converts hot reload fetch failures into a server status indicator showing whether the latest fetch succeeded or failed. Callback fetch failures still appear as errors but have a clearer message.
1111

1212
### Fixed
13+
- [#1255](https://github.com/plotly/dash/pull/1255) Hard hot reload targets only the current window, not the top - so if your app is in an iframe you will only reload the app
1314
- [#1249](https://github.com/plotly/dash/pull/1249) Fixes [#919](https://github.com/plotly/dash/issues/919) so `dash.testing` is compatible with more `pytest` plugins, particularly `pytest-flake8` and `pytest-black`.
1415
- [#1248](https://github.com/plotly/dash/pull/1248) Fixes [#1245](https://github.com/plotly/dash/issues/1245), so you can use prop persistence with components that have dict IDs, ie for pattern-matching callbacks.
1516
- [#1185](https://github.com/plotly/dash/pull/1185) Sort asset directories, same as we sort files inside those directories. This way if you need your assets loaded in a certain order, you can add prefixes to subdirectory names and enforce that order.

Diff for: dash-renderer/src/components/core/Reloader.react.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ class Reloader extends React.Component {
148148
// Assets file have changed
149149
// or a component lib has been added/removed -
150150
// Must do a hard reload
151-
window.top.location.reload();
151+
window.location.reload();
152152
}
153153
} else {
154154
// Backend code changed - can do a soft reload in place

Diff for: tests/integration/devtools/hr_assets/hot_reload.js

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2+
window.cheese = 'roquefort';

Diff for: tests/integration/devtools/test_hot_reload.py

+52-11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import os
22
from time import sleep
33

4+
from dash.testing.wait import until
45
import dash_html_components as html
56
import dash
67
from dash.dependencies import Input, Output
@@ -13,6 +14,24 @@
1314
}
1415
"""
1516

17+
GOUDA = """
18+
window.cheese = 'gouda';
19+
"""
20+
21+
22+
def replace_file(filename, new_content):
23+
path = os.path.join(
24+
os.path.dirname(__file__), "hr_assets", filename
25+
)
26+
with open(path, "r+") as fp:
27+
sleep(1) # ensure a new mod time
28+
old_content = fp.read()
29+
fp.truncate(0)
30+
fp.seek(0)
31+
fp.write(new_content)
32+
33+
return path, old_content
34+
1635

1736
def test_dvhr001_hot_reload(dash_duo):
1837
app = dash.Dash(__name__, assets_folder="hr_assets")
@@ -42,15 +61,12 @@ def new_text(n):
4261
"#hot-reload-content", "background-color", "rgba(0, 0, 255, 1)"
4362
)
4463

45-
hot_reload_file = os.path.join(
46-
os.path.dirname(__file__), "hr_assets", "hot_reload.css"
47-
)
48-
with open(hot_reload_file, "r+") as fp:
49-
sleep(1) # ensure a new mod time
50-
old_content = fp.read()
51-
fp.truncate(0)
52-
fp.seek(0)
53-
fp.write(RED_BG)
64+
# set a global var - if we soft reload it should still be there,
65+
# hard reload will delete it
66+
dash_duo.driver.execute_script("window.someVar = 42;")
67+
assert dash_duo.driver.execute_script("return window.someVar") == 42
68+
69+
soft_reload_file, old_soft = replace_file("hot_reload.css", RED_BG)
5470

5571
try:
5672
# red is live changed during the test execution
@@ -59,13 +75,38 @@ def new_text(n):
5975
)
6076
finally:
6177
sleep(1) # ensure a new mod time
62-
with open(hot_reload_file, "w") as f:
63-
f.write(old_content)
78+
with open(soft_reload_file, "w") as f:
79+
f.write(old_soft)
6480

6581
dash_duo.wait_for_style_to_equal(
6682
"#hot-reload-content", "background-color", "rgba(0, 0, 255, 1)"
6783
)
6884

85+
# only soft reload, someVar is still there
86+
assert dash_duo.driver.execute_script("return window.someVar") == 42
87+
88+
assert dash_duo.driver.execute_script("return window.cheese") == "roquefort"
89+
90+
hard_reload_file, old_hard = replace_file("hot_reload.js", GOUDA)
91+
92+
try:
93+
until(
94+
lambda: dash_duo.driver.execute_script("return window.cheese") == "gouda",
95+
timeout=3
96+
)
97+
finally:
98+
sleep(1) # ensure a new mod time
99+
with open(hard_reload_file, "w") as f:
100+
f.write(old_hard)
101+
102+
until(
103+
lambda: dash_duo.driver.execute_script("return window.cheese") == "roquefort",
104+
timeout=3
105+
)
106+
107+
# we've done a hard reload so someVar is gone
108+
assert dash_duo.driver.execute_script("return window.someVar") is None
109+
69110
# Now check the server status indicator functionality
70111

71112
dash_duo.find_element(".dash-debug-menu").click()

Diff for: tests/integration/renderer/test_due_diligence.py

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ def test_rddd001_initial_state(dash_duo):
5454
# fmt:on
5555

5656
dash_duo.start_server(app)
57+
dash_duo.wait_for_text_to_equal(r"#p\.c\.5", "")
5758

5859
# Note: this .html file shows there's no undo/redo button by default
5960
with open(

0 commit comments

Comments
 (0)