[go: nahoru, domu]

blob: d41f57f1e14b6d5557512f4b8b23dbcf7e4815b0 [file] [log] [blame]
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/user_agent/user_agent_metadata.h"
#include "third_party/blink/public/web/web_view.h"
#include "third_party/blink/renderer/core/frame/frame_test_helpers.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/policy_container.h"
#include "third_party/blink/renderer/core/html/html_anchor_element.h"
#include "third_party/blink/renderer/core/page/chrome_client_impl.h"
#include "third_party/blink/renderer/core/testing/mock_policy_container_host.h"
#include "third_party/blink/renderer/core/testing/sim/sim_request.h"
#include "third_party/blink/renderer/core/testing/sim/sim_test.h"
#include "third_party/blink/renderer/platform/testing/task_environment.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
#include "third_party/blink/renderer/platform/testing/url_test_helpers.h"
namespace blink {
class FrameLoaderSimTest : public SimTest {
public:
FrameLoaderSimTest() = default;
void SetUp() override {
SimTest::SetUp();
WebView().MainFrameViewWidget()->UpdateAllLifecyclePhases(
DocumentUpdateReason::kTest);
}
};
// Ensure that the load event progress is progressed through BeforeUnload only
// if the event is uncanceled.
TEST_F(FrameLoaderSimTest, LoadEventProgressBeforeUnloadCanceled) {
SimRequest request("https://example.com/test.html", "text/html");
SimRequest request_a("https://example.com/subframe-a.html", "text/html");
SimRequest request_b("https://example.com/subframe-b.html", "text/html");
SimRequest request_c("https://example.com/subframe-c.html", "text/html");
SimRequest request_unload("https://example.com/next-page.html", "text/html");
LoadURL("https://example.com/test.html");
request.Complete(R"HTML(
<!DOCTYPE html>
<iframe src="subframe-a.html"></iframe>
)HTML");
request_a.Complete(R"HTML(
<!DOCTYPE html>
<iframe src="subframe-b.html"></iframe>
<a id="link" href="next-page.html">Next Page</a>
)HTML");
request_b.Complete(R"HTML(
<!DOCTYPE html>
<script>
window.onbeforeunload = (e) => {
e.returnValue = '';
e.preventDefault();
};
</script>
<iframe src="subframe-c.html"></iframe>
)HTML");
request_c.Complete(R"HTML(
<!DOCTYPE html>
)HTML");
Compositor().BeginFrame();
auto* main_frame = To<LocalFrame>(GetDocument().GetPage()->MainFrame());
auto* frame_a = To<LocalFrame>(main_frame->Tree().FirstChild());
auto* frame_b = To<LocalFrame>(frame_a->Tree().FirstChild());
auto* frame_c = To<LocalFrame>(frame_b->Tree().FirstChild());
ASSERT_FALSE(main_frame->GetDocument()->BeforeUnloadStarted());
ASSERT_FALSE(frame_a->GetDocument()->BeforeUnloadStarted());
ASSERT_FALSE(frame_b->GetDocument()->BeforeUnloadStarted());
ASSERT_FALSE(frame_c->GetDocument()->BeforeUnloadStarted());
// We'll only allow canceling a beforeunload if there's a sticky user
// activation present so simulate a user gesture.
LocalFrame::NotifyUserActivation(
frame_b, mojom::UserActivationNotificationType::kTest);
auto& chrome_client =
To<ChromeClientImpl>(WebView().GetPage()->GetChromeClient());
// Simulate the user canceling the navigation away. Since the navigation was
// "canceled", we expect that each of the frames should remain in their state
// before the beforeunload was dispatched.
{
chrome_client.SetBeforeUnloadConfirmPanelResultForTesting(false);
// Note: We can't perform a navigation to check this because the
// beforeunload event is dispatched from content's RenderFrameImpl, Blink
// tests mock this out using a WebFrameTestProxy which doesn't check
// beforeunload before navigating.
ASSERT_FALSE(frame_a->Loader().ShouldClose());
EXPECT_FALSE(main_frame->GetDocument()->BeforeUnloadStarted());
EXPECT_FALSE(frame_a->GetDocument()->BeforeUnloadStarted());
EXPECT_FALSE(frame_b->GetDocument()->BeforeUnloadStarted());
EXPECT_FALSE(frame_c->GetDocument()->BeforeUnloadStarted());
}
// Now test the opposite, the user allowing the navigation away.
{
chrome_client.SetBeforeUnloadConfirmPanelResultForTesting(true);
ASSERT_TRUE(frame_a->Loader().ShouldClose());
// The navigation was in frame a so it shouldn't affect the parent.
EXPECT_FALSE(main_frame->GetDocument()->BeforeUnloadStarted());
EXPECT_TRUE(frame_a->GetDocument()->BeforeUnloadStarted());
EXPECT_TRUE(frame_b->GetDocument()->BeforeUnloadStarted());
EXPECT_TRUE(frame_c->GetDocument()->BeforeUnloadStarted());
}
}
class FrameLoaderTest : public testing::Test {
protected:
void SetUp() override {
web_view_helper_.Initialize();
url_test_helpers::RegisterMockedURLLoad(
url_test_helpers::ToKURL("https://example.com/foo.html"),
test::CoreTestDataPath("foo.html"));
}
void TearDown() override {
url_test_helpers::UnregisterAllURLsAndClearMemoryCache();
}
test::TaskEnvironment task_environment_;
frame_test_helpers::WebViewHelper web_view_helper_;
};
TEST_F(FrameLoaderTest, PolicyContainerIsStoredOnCommitNavigation) {
WebViewImpl* web_view_impl = web_view_helper_.Initialize();
const KURL& url = KURL(NullURL(), "https://www.example.com/bar.html");
std::unique_ptr<WebNavigationParams> params =
WebNavigationParams::CreateWithHTMLBufferForTesting(
SharedBuffer::Create(), url);
MockPolicyContainerHost mock_policy_container_host;
params->policy_container = std::make_unique<WebPolicyContainer>(
WebPolicyContainerPolicies{
network::mojom::CrossOriginEmbedderPolicyValue::kNone,
network::mojom::ReferrerPolicy::kAlways,
WebVector<WebContentSecurityPolicy>(),
},
mock_policy_container_host.BindNewEndpointAndPassDedicatedRemote());
LocalFrame* local_frame =
To<LocalFrame>(web_view_impl->GetPage()->MainFrame());
local_frame->Loader().CommitNavigation(std::move(params), nullptr);
EXPECT_EQ(*mojom::blink::PolicyContainerPolicies::New(
network::CrossOriginEmbedderPolicy(
network::mojom::CrossOriginEmbedderPolicyValue::kNone),
network::mojom::ReferrerPolicy::kAlways,
Vector<network::mojom::blink::ContentSecurityPolicyPtr>(),
/*anonymous=*/false, network::mojom::WebSandboxFlags::kNone,
network::mojom::blink::IPAddressSpace::kUnknown,
/*can_navigate_top_without_user_gesture=*/true,
/*allow_cross_origin_isolation_under_initial_empty_document=*/
false),
local_frame->DomWindow()->GetPolicyContainer()->GetPolicies());
}
} // namespace blink