1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/macros.h"
6 #include "base/values.h"
7 #include "chrome/browser/extensions/api/web_navigation/frame_navigation_state.h"
8 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
9 #include "chrome/test/base/testing_profile.h"
10 #include "testing/gtest/include/gtest/gtest.h"
12 namespace extensions
{
14 class FrameNavigationStateTest
: public ChromeRenderViewHostTestHarness
{
16 void SetUp() override
{
17 ChromeRenderViewHostTestHarness::SetUp();
19 content::RenderFrameHostTester::For(main_rfh())
20 ->InitializeRenderFrameIfNeeded();
24 FrameNavigationStateTest() {}
25 ~FrameNavigationStateTest() override
{}
27 FrameNavigationState navigation_state_
;
30 DISALLOW_COPY_AND_ASSIGN(FrameNavigationStateTest
);
33 // Test that a frame is correctly tracked, and removed once the tab contents
35 TEST_F(FrameNavigationStateTest
, TrackFrame
) {
36 const GURL
url1("http://www.google.com/");
37 const GURL
url2("http://mail.google.com/");
39 // Create a main frame.
40 EXPECT_FALSE(navigation_state_
.CanSendEvents(main_rfh()));
41 EXPECT_FALSE(navigation_state_
.IsValidFrame(main_rfh()));
42 navigation_state_
.StartTrackingNavigation(main_rfh(), url1
, false, false);
43 navigation_state_
.SetNavigationCommitted(main_rfh());
44 EXPECT_TRUE(navigation_state_
.CanSendEvents(main_rfh()));
45 EXPECT_TRUE(navigation_state_
.IsValidFrame(main_rfh()));
48 content::RenderFrameHost
* sub_frame
=
49 content::RenderFrameHostTester::For(main_rfh())->AppendChild("child");
50 EXPECT_FALSE(navigation_state_
.CanSendEvents(sub_frame
));
51 EXPECT_FALSE(navigation_state_
.IsValidFrame(sub_frame
));
52 navigation_state_
.StartTrackingNavigation(sub_frame
, url2
, false, false);
53 navigation_state_
.SetNavigationCommitted(sub_frame
);
54 EXPECT_TRUE(navigation_state_
.CanSendEvents(sub_frame
));
55 EXPECT_TRUE(navigation_state_
.IsValidFrame(sub_frame
));
58 EXPECT_EQ(url1
, navigation_state_
.GetUrl(main_rfh()));
59 EXPECT_EQ(url2
, navigation_state_
.GetUrl(sub_frame
));
62 navigation_state_
.FrameHostDeleted(sub_frame
);
63 EXPECT_FALSE(navigation_state_
.CanSendEvents(sub_frame
));
64 EXPECT_FALSE(navigation_state_
.IsValidFrame(sub_frame
));
66 navigation_state_
.FrameHostDeleted(main_rfh());
67 EXPECT_FALSE(navigation_state_
.CanSendEvents(main_rfh()));
68 EXPECT_FALSE(navigation_state_
.IsValidFrame(main_rfh()));
71 // Test that no events can be sent for a frame after an error occurred, but
72 // before a new navigation happened in this frame.
73 TEST_F(FrameNavigationStateTest
, ErrorState
) {
74 const GURL
url("http://www.google.com/");
76 navigation_state_
.StartTrackingNavigation(main_rfh(), url
, false, false);
77 EXPECT_TRUE(navigation_state_
.CanSendEvents(main_rfh()));
78 EXPECT_FALSE(navigation_state_
.GetErrorOccurredInFrame(main_rfh()));
80 // After an error occurred, no further events should be sent.
81 navigation_state_
.SetErrorOccurredInFrame(main_rfh());
82 EXPECT_FALSE(navigation_state_
.CanSendEvents(main_rfh()));
83 EXPECT_TRUE(navigation_state_
.GetErrorOccurredInFrame(main_rfh()));
85 // Navigations to a network error page should be ignored.
86 navigation_state_
.StartTrackingNavigation(main_rfh(), GURL(), true, false);
87 EXPECT_FALSE(navigation_state_
.CanSendEvents(main_rfh()));
88 EXPECT_TRUE(navigation_state_
.GetErrorOccurredInFrame(main_rfh()));
90 // However, when the frame navigates again, it should send events again.
91 navigation_state_
.StartTrackingNavigation(main_rfh(), url
, false, false);
92 EXPECT_TRUE(navigation_state_
.CanSendEvents(main_rfh()));
93 EXPECT_FALSE(navigation_state_
.GetErrorOccurredInFrame(main_rfh()));
96 // Tests that for a sub frame, no events are send after an error occurred, but
97 // before a new navigation happened in this frame.
98 TEST_F(FrameNavigationStateTest
, ErrorStateFrame
) {
99 const GURL
url("http://www.google.com/");
101 content::RenderFrameHost
* sub_frame
=
102 content::RenderFrameHostTester::For(main_rfh())->AppendChild("child");
103 navigation_state_
.StartTrackingNavigation(main_rfh(), url
, false, false);
104 navigation_state_
.StartTrackingNavigation(sub_frame
, url
, false, false);
105 EXPECT_TRUE(navigation_state_
.CanSendEvents(main_rfh()));
106 EXPECT_TRUE(navigation_state_
.CanSendEvents(sub_frame
));
108 // After an error occurred, no further events should be sent.
109 navigation_state_
.SetErrorOccurredInFrame(sub_frame
);
110 EXPECT_TRUE(navigation_state_
.CanSendEvents(main_rfh()));
111 EXPECT_FALSE(navigation_state_
.CanSendEvents(sub_frame
));
113 // Navigations to a network error page should be ignored.
114 navigation_state_
.StartTrackingNavigation(sub_frame
, GURL(), true, false);
115 EXPECT_TRUE(navigation_state_
.CanSendEvents(main_rfh()));
116 EXPECT_FALSE(navigation_state_
.CanSendEvents(sub_frame
));
118 // However, when the frame navigates again, it should send events again.
119 navigation_state_
.StartTrackingNavigation(sub_frame
, url
, false, false);
120 EXPECT_TRUE(navigation_state_
.CanSendEvents(main_rfh()));
121 EXPECT_TRUE(navigation_state_
.CanSendEvents(sub_frame
));
124 // Tests that no events are send for a not web-safe scheme.
125 TEST_F(FrameNavigationStateTest
, WebSafeScheme
) {
126 const GURL
url("unsafe://www.google.com/");
128 navigation_state_
.StartTrackingNavigation(main_rfh(), url
, false, false);
129 EXPECT_FALSE(navigation_state_
.CanSendEvents(main_rfh()));
132 // Test for <iframe srcdoc=""> frames.
133 TEST_F(FrameNavigationStateTest
, SrcDoc
) {
134 const GURL
url("http://www.google.com/");
135 const GURL
blank("about:blank");
136 const GURL
srcdoc("about:srcdoc");
138 content::RenderFrameHost
* sub_frame
=
139 content::RenderFrameHostTester::For(main_rfh())->AppendChild("child");
140 navigation_state_
.StartTrackingNavigation(main_rfh(), url
, false, false);
141 navigation_state_
.StartTrackingNavigation(sub_frame
, blank
, false, true);
142 EXPECT_TRUE(navigation_state_
.CanSendEvents(main_rfh()));
143 EXPECT_TRUE(navigation_state_
.CanSendEvents(sub_frame
));
145 EXPECT_EQ(url
, navigation_state_
.GetUrl(main_rfh()));
146 EXPECT_EQ(srcdoc
, navigation_state_
.GetUrl(sub_frame
));
148 EXPECT_TRUE(navigation_state_
.IsValidUrl(srcdoc
));
151 // Test that an individual frame can be detached.
152 TEST_F(FrameNavigationStateTest
, DetachFrame
) {
153 const GURL
url1("http://www.google.com/");
154 const GURL
url2("http://mail.google.com/");
156 // Create a main frame.
157 EXPECT_FALSE(navigation_state_
.CanSendEvents(main_rfh()));
158 EXPECT_FALSE(navigation_state_
.IsValidFrame(main_rfh()));
159 navigation_state_
.StartTrackingNavigation(main_rfh(), url1
, false, false);
160 navigation_state_
.SetNavigationCommitted(main_rfh());
161 EXPECT_TRUE(navigation_state_
.CanSendEvents(main_rfh()));
162 EXPECT_TRUE(navigation_state_
.IsValidFrame(main_rfh()));
165 content::RenderFrameHost
* sub_frame
=
166 content::RenderFrameHostTester::For(main_rfh())->AppendChild("child");
167 EXPECT_FALSE(navigation_state_
.CanSendEvents(sub_frame
));
168 EXPECT_FALSE(navigation_state_
.IsValidFrame(sub_frame
));
169 navigation_state_
.StartTrackingNavigation(sub_frame
, url2
, false, false);
170 navigation_state_
.SetNavigationCommitted(sub_frame
);
171 EXPECT_TRUE(navigation_state_
.CanSendEvents(sub_frame
));
172 EXPECT_TRUE(navigation_state_
.IsValidFrame(sub_frame
));
174 // Check frame state.
175 EXPECT_EQ(url1
, navigation_state_
.GetUrl(main_rfh()));
176 EXPECT_EQ(url2
, navigation_state_
.GetUrl(sub_frame
));
179 navigation_state_
.FrameHostDeleted(sub_frame
);
180 EXPECT_EQ(url1
, navigation_state_
.GetUrl(main_rfh()));
181 EXPECT_FALSE(navigation_state_
.CanSendEvents(sub_frame
));
182 EXPECT_FALSE(navigation_state_
.IsValidFrame(sub_frame
));
185 } // namespace extensions