Skip to content

Commit

Permalink
Merge pull request #2815 from rmartin16/android-enable-dom-storage
Browse files Browse the repository at this point in the history
Enable DOM storage for Android WebView
  • Loading branch information
freakboy3742 authored Sep 6, 2024
2 parents ed1f41a + 50705e4 commit 63480d5
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 9 deletions.
1 change: 1 addition & 0 deletions android/src/toga_android/widgets/webview.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def create(self):
self.settings = self.native.getSettings()
self.default_user_agent = self.settings.getUserAgentString()
self.settings.setJavaScriptEnabled(True)
self.settings.setDomStorageEnabled(True)
# enable pinch-to-zoom without the deprecated on-screen controls
self.settings.setBuiltInZoomControls(True)
self.settings.setDisplayZoomControls(False)
Expand Down
1 change: 1 addition & 0 deletions changes/2767.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DOM storage is now enabled for WebView on Android.
45 changes: 36 additions & 9 deletions testbed/tests/widgets/test_webview.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ async def widget(on_load):


async def test_set_url(widget, probe, on_load):
"The URL can be set"
"""The URL can be set."""
widget.url = "https://github.com/beeware"

# Wait for the content to be loaded
Expand All @@ -130,7 +130,7 @@ async def test_set_url(widget, probe, on_load):


async def test_clear_url(widget, probe, on_load):
"The URL can be cleared"
"""The URL can be cleared."""
widget.url = None

# Wait for the content to be cleared
Expand All @@ -145,7 +145,7 @@ async def test_clear_url(widget, probe, on_load):


async def test_load_empty_url(widget, probe, on_load):
"An empty URL can be loaded asynchronously into the view"
"""An empty URL can be loaded asynchronously into the view."""
await wait_for(
widget.load_url(None),
LOAD_TIMEOUT,
Expand All @@ -163,7 +163,7 @@ async def test_load_empty_url(widget, probe, on_load):


async def test_load_url(widget, probe, on_load):
"A URL can be loaded into the view"
"""A URL can be loaded into the view."""
await wait_for(
widget.load_url("https://github.com/beeware"),
LOAD_TIMEOUT,
Expand All @@ -181,7 +181,7 @@ async def test_load_url(widget, probe, on_load):


async def test_static_content(widget, probe, on_load):
"Static content can be loaded into the page"
"""Static content can be loaded into the page."""
widget.set_content("https://example.com/", "<h1>Nice page</h1>")

# DOM loads aren't instantaneous; wait for the URL to appear
Expand All @@ -205,7 +205,7 @@ async def test_user_agent(widget, probe):


async def test_evaluate_javascript(widget, probe):
"JavaScript can be evaluated"
"""JavaScript can be evaluated."""
on_result_handler = Mock()

for expression, expected in [
Expand All @@ -232,7 +232,7 @@ async def test_evaluate_javascript(widget, probe):


async def test_evaluate_javascript_no_handler(widget, probe):
"A handler isn't needed to evaluate JavaScript"
"""A handler isn't needed to evaluate JavaScript."""
result = await wait_for(
widget.evaluate_javascript("37 + 42"),
JS_TIMEOUT,
Expand All @@ -250,7 +250,7 @@ def javascript_error_context(probe):


async def test_evaluate_javascript_error(widget, probe):
"If JavaScript content raises an error, the error is propagated"
"""If JavaScript content raises an error, the error is propagated."""
on_result_handler = Mock()

with javascript_error_context(probe):
Expand Down Expand Up @@ -278,7 +278,7 @@ async def test_evaluate_javascript_error(widget, probe):


async def test_evaluate_javascript_error_without_handler(widget, probe):
"A handler isn't needed to propagate a JavaScript error"
"""A handler isn't needed to propagate a JavaScript error."""
with javascript_error_context(probe):
result = await wait_for(
widget.evaluate_javascript("not valid js"),
Expand All @@ -287,3 +287,30 @@ async def test_evaluate_javascript_error_without_handler(widget, probe):
# If the backend supports exceptions, the previous line should have raised one.
assert not probe.javascript_supports_exception
assert result is None


async def test_dom_storage_enabled(widget, probe, on_load):
"""Ensure DOM storage is enabled."""
# a page must be loaded to access local storage
await wait_for(
widget.load_url("https://example.com/"),
LOAD_TIMEOUT,
)
# small pause to ensure javascript can run without security errors
await asyncio.sleep(1)

expected_value = "Hello World"
expression = f"""\
(function isLocalStorageAvailable(){{
var test = 'testkey';
try {{
localStorage.setItem(test, "{expected_value}");
item = localStorage.getItem(test);
localStorage.removeItem(test);
return item;
}} catch(e) {{
return String(e);
}}
}})()"""
result = await wait_for(widget.evaluate_javascript(expression), JS_TIMEOUT)
assert result == expected_value

0 comments on commit 63480d5

Please sign in to comment.