Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hard reload targets just this window #1255

Merged
merged 5 commits into from
May 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- [#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.

### Fixed
- [#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
- [#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`.
- [#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.
- [#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.
Expand Down
2 changes: 1 addition & 1 deletion dash-renderer/src/components/core/Reloader.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ class Reloader extends React.Component {
// Assets file have changed
// or a component lib has been added/removed -
// Must do a hard reload
window.top.location.reload();
window.location.reload();
}
} else {
// Backend code changed - can do a soft reload in place
Expand Down
2 changes: 2 additions & 0 deletions tests/integration/devtools/hr_assets/hot_reload.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

window.cheese = 'roquefort';
63 changes: 52 additions & 11 deletions tests/integration/devtools/test_hot_reload.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os
from time import sleep

from dash.testing.wait import until
import dash_html_components as html
import dash
from dash.dependencies import Input, Output
Expand All @@ -13,6 +14,24 @@
}
"""

GOUDA = """
window.cheese = 'gouda';
"""


def replace_file(filename, new_content):
path = os.path.join(
os.path.dirname(__file__), "hr_assets", filename
)
with open(path, "r+") as fp:
sleep(1) # ensure a new mod time
old_content = fp.read()
fp.truncate(0)
fp.seek(0)
fp.write(new_content)

return path, old_content


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

hot_reload_file = os.path.join(
os.path.dirname(__file__), "hr_assets", "hot_reload.css"
)
with open(hot_reload_file, "r+") as fp:
sleep(1) # ensure a new mod time
old_content = fp.read()
fp.truncate(0)
fp.seek(0)
fp.write(RED_BG)
# set a global var - if we soft reload it should still be there,
# hard reload will delete it
dash_duo.driver.execute_script("window.someVar = 42;")
assert dash_duo.driver.execute_script("return window.someVar") == 42

soft_reload_file, old_soft = replace_file("hot_reload.css", RED_BG)

try:
# red is live changed during the test execution
Expand All @@ -59,13 +75,38 @@ def new_text(n):
)
finally:
sleep(1) # ensure a new mod time
with open(hot_reload_file, "w") as f:
f.write(old_content)
with open(soft_reload_file, "w") as f:
f.write(old_soft)

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

# only soft reload, someVar is still there
assert dash_duo.driver.execute_script("return window.someVar") == 42

assert dash_duo.driver.execute_script("return window.cheese") == "roquefort"

hard_reload_file, old_hard = replace_file("hot_reload.js", GOUDA)

try:
until(
lambda: dash_duo.driver.execute_script("return window.cheese") == "gouda",
timeout=3
)
finally:
sleep(1) # ensure a new mod time
with open(hard_reload_file, "w") as f:
f.write(old_hard)

until(
lambda: dash_duo.driver.execute_script("return window.cheese") == "roquefort",
timeout=3
)

# we've done a hard reload so someVar is gone
assert dash_duo.driver.execute_script("return window.someVar") is None

# Now check the server status indicator functionality

dash_duo.find_element(".dash-debug-menu").click()
Expand Down
1 change: 1 addition & 0 deletions tests/integration/renderer/test_due_diligence.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ def test_rddd001_initial_state(dash_duo):
# fmt:on

dash_duo.start_server(app)
dash_duo.wait_for_text_to_equal(r"#p\.c\.5", "")

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