diff --git a/src/slic3r/GUI/WebMediaController.cpp b/src/slic3r/GUI/WebMediaController.cpp
index 4e03ce6562..fe4b94d3ac 100644
--- a/src/slic3r/GUI/WebMediaController.cpp
+++ b/src/slic3r/GUI/WebMediaController.cpp
@@ -4,13 +4,23 @@
namespace Slic3r { namespace GUI {
-WebMediaController::WebMediaController(wxWebView* webview) : m_webview(webview)
+namespace {
+
+void initialize_webview(wxWebView* webview)
{
- if (!m_webview)
+ if (!webview)
return;
- m_webview->SetBackgroundColour(*wxBLACK);
- m_webview->SetPage("
", "");
+ webview->SetBackgroundColour(*wxBLACK);
+ webview->SetPage("", "");
+}
+
+} // namespace
+
+WebMediaController::WebMediaController(wxWebView* webview)
+ : m_webview(webview)
+{
+ initialize_webview(m_webview);
}
void WebMediaController::Load(wxURI url)
diff --git a/src/slic3r/GUI/WebMediaController.hpp b/src/slic3r/GUI/WebMediaController.hpp
index 566bf65e96..e7756d8977 100644
--- a/src/slic3r/GUI/WebMediaController.hpp
+++ b/src/slic3r/GUI/WebMediaController.hpp
@@ -23,7 +23,7 @@ public:
void Stop() override;
private:
- wxWebView* m_webview;
+ wxWebView* m_webview = nullptr;
std::string m_url;
CameraStreamMode m_stream_mode = CameraStreamMode::http;
};
diff --git a/tests/slic3rutils/CMakeLists.txt b/tests/slic3rutils/CMakeLists.txt
index a89da36f53..77063c752f 100644
--- a/tests/slic3rutils/CMakeLists.txt
+++ b/tests/slic3rutils/CMakeLists.txt
@@ -7,6 +7,7 @@ add_executable(${_TEST_NAME}_tests
test_filament_bitmap_utils.cpp
test_device_progress.cpp
test_device_manager_integration.cpp
+ test_web_media_controller.cpp
test_network_versions.cpp
test_action_source.cpp
test_plugin_host_api.cpp
diff --git a/tests/slic3rutils/test_web_media_controller.cpp b/tests/slic3rutils/test_web_media_controller.cpp
new file mode 100644
index 0000000000..2933145d8d
--- /dev/null
+++ b/tests/slic3rutils/test_web_media_controller.cpp
@@ -0,0 +1,117 @@
+#include
+
+#include
+
+#include
+#include
+
+#include
+#include
+
+using namespace Slic3r;
+using namespace Slic3r::GUI;
+
+namespace {
+
+class StubWebView final : public wxWebView
+{
+public:
+ bool SetBackgroundColour(const wxColour&) override
+ {
+ events.emplace_back("background");
+ return true;
+ }
+
+ bool Create(wxWindow*, wxWindowID, const wxString&, const wxPoint&, const wxSize&, long, const wxString&) override { return true; }
+ wxString GetCurrentTitle() const override { return {}; }
+ wxString GetCurrentURL() const override { return {}; }
+ bool IsBusy() const override { return false; }
+ bool IsEditable() const override { return false; }
+ void LoadURL(const wxString& url) override
+ {
+ events.emplace_back("url");
+ loaded_url = url.ToStdString();
+ }
+ void Print() override {}
+ void RegisterHandler(wxSharedPtr) override {}
+ void Reload(wxWebViewReloadFlags) override {}
+ void SetEditable(bool) override {}
+ void Stop() override { events.emplace_back("stop"); }
+ bool CanGoBack() const override { return false; }
+ bool CanGoForward() const override { return false; }
+ void GoBack() override {}
+ void GoForward() override {}
+ void ClearHistory() override { events.emplace_back("history"); }
+ void EnableHistory(bool) override {}
+ wxVector> GetBackwardHistory() override { return {}; }
+ wxVector> GetForwardHistory() override { return {}; }
+ void LoadHistoryItem(wxSharedPtr) override {}
+ bool CanSetZoomType(wxWebViewZoomType) const override { return false; }
+ float GetZoomFactor() const override { return 1.0f; }
+ wxWebViewZoomType GetZoomType() const override { return wxWEBVIEW_ZOOM_TYPE_LAYOUT; }
+ void SetZoomFactor(float) override {}
+ void SetZoomType(wxWebViewZoomType) override {}
+ bool CanUndo() const override { return false; }
+ bool CanRedo() const override { return false; }
+ void Undo() override {}
+ void Redo() override {}
+ void* GetNativeBackend() const override { return nullptr; }
+
+ bool RunScript(const wxString& javascript, wxString*) const override
+ {
+ events.emplace_back("script");
+ script = javascript.ToStdString();
+ return true;
+ }
+
+protected:
+ void DoSetPage(const wxString& html, const wxString& base_url) override
+ {
+ events.emplace_back("page");
+ page = html.ToStdString();
+ page_base = base_url.ToStdString();
+ }
+
+public:
+ mutable std::vector events;
+ std::string page;
+ std::string page_base;
+ mutable std::string script;
+ std::string loaded_url;
+};
+
+} // namespace
+
+TEST_CASE("Web media controller tears down a snapshot lifecycle", "[WebMediaController][integration]")
+{
+ wxInitializer wx_init;
+ REQUIRE(wx_init.IsOk());
+
+ StubWebView view;
+ WebMediaController controller(&view);
+
+ controller.set_mode(CameraStreamMode::http_snapshot);
+ controller.Load(wxURI("http://camera.example/frame.jpg"));
+ controller.Play();
+
+ REQUIRE(view.events.size() == 3);
+ CHECK(view.events[0] == "background");
+ CHECK(view.events[1] == "page");
+ CHECK(view.events[2] == "page");
+ CHECK(view.page.find("stopCameraRefresh") != std::string::npos);
+ CHECK(view.page.find("http://camera.example/frame.jpg") != std::string::npos);
+
+ controller.Stop();
+
+ REQUIRE(view.events.size() == 7);
+ CHECK(view.events[3] == "script");
+ CHECK(view.events[4] == "stop");
+ CHECK(view.events[5] == "page");
+ CHECK(view.events[6] == "history");
+ CHECK(view.script == "if(typeof stopCameraRefresh==='function') stopCameraRefresh();");
+ CHECK(view.page.empty());
+ CHECK(view.page_base == "about:blank");
+
+ controller.Play();
+ CHECK(view.page.find("http://camera.example/frame.jpg") == std::string::npos);
+}