| // Copyright 2018 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <fuchsia/sys/cpp/fidl.h> |
| #include <lib/fit/function.h> |
| #include <lib/gtest/real_loop_fixture.h> |
| #include <lib/sys/cpp/service_directory.h> |
| #include <lib/syslog/cpp/macros.h> |
| #include <zircon/status.h> |
| |
| #include <gtest/gtest.h> |
| |
| #include "src/chromium/web_runner_tests/test_server.h" |
| #include "src/chromium/web_runner_tests/web_context.h" |
| #include "src/lib/fxl/strings/string_printf.h" |
| |
| // This file contains a subset of adapted Chromium Fuchsia tests to make sure |
| // nothing broke on the import boundary. |
| // |
| // See also: https://chromium.googlesource.com/chromium/src/+/HEAD/fuchsia |
| namespace { |
| |
| // This is a black box smoke test for whether the web runner in a given system |
| // is capable of performing basic operations. |
| // |
| // This tests if launching a component with an HTTP URL triggers an HTTP GET for |
| // the main resource, and if an HTML response with an <img> tag triggers a |
| // subresource load for the image. |
| // |
| // See also: |
| // https://chromium.googlesource.com/chromium/src/+/HEAD/fuchsia/runners/web/web_runner_smoke_test.cc |
| TEST(WebRunnerIntegrationTest, Smoke) { |
| web_runner_tests::TestServer server; |
| FX_CHECK(server.FindAndBindPort()); |
| |
| fuchsia::sys::LaunchInfo launch_info; |
| launch_info.url = fxl::StringPrintf("http://localhost:%d/foo.html", server.port()); |
| |
| fuchsia::sys::LauncherSyncPtr launcher; |
| sys::ServiceDirectory::CreateFromNamespace()->Connect(launcher.NewRequest()); |
| |
| fuchsia::sys::ComponentControllerSyncPtr controller; |
| launcher->CreateComponent(std::move(launch_info), controller.NewRequest()); |
| |
| ASSERT_TRUE(server.Accept()); |
| |
| std::string expected_prefix = "GET /foo.html HTTP"; |
| // We need to overallocate the first time to drain the read since we expect |
| // the subsresource load on the same connection. |
| std::string buf(4096, 0); |
| ASSERT_TRUE(server.Read(&buf)); |
| EXPECT_EQ(expected_prefix, buf.substr(0, expected_prefix.size())); |
| |
| FX_CHECK(server.WriteContent("<!doctype html><img src=\"/img.png\">")); |
| |
| expected_prefix = "GET /img.png HTTP"; |
| buf.resize(expected_prefix.size()); |
| ASSERT_TRUE(server.Read(&buf)); |
| |
| ASSERT_GE(buf.size(), expected_prefix.size()); |
| EXPECT_EQ(expected_prefix, std::string(buf.data(), expected_prefix.size())); |
| } |
| |
| class MockNavigationEventListener : public fuchsia::web::NavigationEventListener { |
| public: |
| // |fuchsia::web::NavigationEventListener| |
| void OnNavigationStateChanged(fuchsia::web::NavigationState change, |
| OnNavigationStateChangedCallback callback) override { |
| if (on_navigation_state_changed_) { |
| on_navigation_state_changed_(std::move(change)); |
| } |
| |
| callback(); |
| } |
| |
| void set_on_navigation_state_changed(fit::function<void(fuchsia::web::NavigationState)> fn) { |
| on_navigation_state_changed_ = std::move(fn); |
| } |
| |
| private: |
| fit::function<void(fuchsia::web::NavigationState)> on_navigation_state_changed_; |
| }; |
| |
| class ChromiumAppTest : public gtest::RealLoopFixture { |
| protected: |
| ChromiumAppTest() |
| : web_context_(sys::ComponentContext::CreateAndServeOutgoingDirectory().get(), |
| fuchsia::web::ContextFeatureFlags()) {} |
| |
| WebContext* web_context() { return &web_context_; } |
| |
| private: |
| WebContext web_context_; |
| }; |
| |
| // This test ensures that we can interact with the fuchsia.web FIDL. |
| // |
| // See also |
| // https://chromium.googlesource.com/chromium/src/+/HEAD/fuchsia/engine/browser/context_impl_browsertest.cc |
| TEST_F(ChromiumAppTest, CreateAndNavigate) { |
| MockNavigationEventListener navigation_event_listener; |
| fidl::Binding<fuchsia::web::NavigationEventListener> navigation_event_listener_binding( |
| &navigation_event_listener); |
| web_context()->web_frame()->SetNavigationEventListener( |
| navigation_event_listener_binding.NewBinding()); |
| navigation_event_listener_binding.set_error_handler([](zx_status_t status) { |
| FAIL() << "navigation_event_listener_binding: " << zx_status_get_string(status); |
| }); |
| |
| std::string observed_url; |
| std::string observed_title; |
| |
| navigation_event_listener.set_on_navigation_state_changed( |
| [this, &navigation_event_listener, &observed_url, |
| &observed_title](fuchsia::web::NavigationState change) { |
| if (change.has_url()) { |
| observed_url = change.url(); |
| } |
| if (change.has_title()) { |
| observed_title = change.title(); |
| } |
| |
| if (change.has_page_type()) { |
| EXPECT_EQ(change.page_type(), fuchsia::web::PageType::NORMAL); |
| } |
| |
| if (change.has_is_main_document_loaded() && change.is_main_document_loaded()) { |
| navigation_event_listener.set_on_navigation_state_changed(nullptr); |
| QuitLoop(); |
| } |
| }); |
| |
| web_runner_tests::TestServer server; |
| FX_CHECK(server.FindAndBindPort()); |
| |
| const std::string url = fxl::StringPrintf("http://localhost:%d/foo.html", server.port()); |
| web_context()->Navigate(url); |
| |
| ASSERT_TRUE(server.Accept()); |
| |
| const std::string expected_prefix = "GET /foo.html HTTP"; |
| std::string buf(expected_prefix.size(), 0); |
| ASSERT_TRUE(server.Read(&buf)); |
| EXPECT_EQ(expected_prefix, buf.substr(0, expected_prefix.size())); |
| FX_CHECK(server.WriteContent(R"(<!doctype html> |
| <html> |
| <head> |
| <title>Test title!</title> |
| </head> |
| </html>)")); |
| |
| EXPECT_FALSE(RunLoopWithTimeout(zx::sec(5))) << "Timed out waiting for navigation events"; |
| |
| EXPECT_EQ(url, observed_url); |
| EXPECT_EQ("Test title!", observed_title); |
| } |
| |
| } // namespace |