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 FrameNavigationStateTest() {}
17 ~FrameNavigationStateTest() override
{}
19 FrameNavigationState navigation_state_
;
22 DISALLOW_COPY_AND_ASSIGN(FrameNavigationStateTest
);
25 // Test that a frame is correctly tracked, and removed once the tab contents
27 TEST_F(FrameNavigationStateTest
, TrackFrame
) {
28 const GURL
url1("http://www.google.com/");
29 const GURL
url2("http://mail.google.com/");
31 // Create a main frame.
32 EXPECT_FALSE(navigation_state_
.CanSendEvents(main_rfh()));
33 EXPECT_FALSE(navigation_state_
.IsValidFrame(main_rfh()));
34 navigation_state_
.StartTrackingNavigation(main_rfh(), url1
, false, false);
35 navigation_state_
.SetNavigationCommitted(main_rfh());
36 EXPECT_TRUE(navigation_state_
.CanSendEvents(main_rfh()));
37 EXPECT_TRUE(navigation_state_
.IsValidFrame(main_rfh()));
40 content::RenderFrameHost
* sub_frame
=
41 content::RenderFrameHostTester::For(main_rfh())->AppendChild("child");
42 EXPECT_FALSE(navigation_state_
.CanSendEvents(sub_frame
));
43 EXPECT_FALSE(navigation_state_
.IsValidFrame(sub_frame
));
44 navigation_state_
.StartTrackingNavigation(sub_frame
, url2
, false, false);
45 navigation_state_
.SetNavigationCommitted(sub_frame
);
46 EXPECT_TRUE(navigation_state_
.CanSendEvents(sub_frame
));
47 EXPECT_TRUE(navigation_state_
.IsValidFrame(sub_frame
));
50 EXPECT_EQ(url1
, navigation_state_
.GetUrl(main_rfh()));
51 EXPECT_EQ(url2
, navigation_state_
.GetUrl(sub_frame
));
54 navigation_state_
.FrameHostDeleted(sub_frame
);
55 EXPECT_FALSE(navigation_state_
.CanSendEvents(sub_frame
));
56 EXPECT_FALSE(navigation_state_
.IsValidFrame(sub_frame
));
58 navigation_state_
.FrameHostDeleted(main_rfh());
59 EXPECT_FALSE(navigation_state_
.CanSendEvents(main_rfh()));
60 EXPECT_FALSE(navigation_state_
.IsValidFrame(main_rfh()));
63 // Test that no events can be sent for a frame after an error occurred, but
64 // before a new navigation happened in this frame.
65 TEST_F(FrameNavigationStateTest
, ErrorState
) {
66 const GURL
url("http://www.google.com/");
68 navigation_state_
.StartTrackingNavigation(main_rfh(), url
, false, false);
69 EXPECT_TRUE(navigation_state_
.CanSendEvents(main_rfh()));
70 EXPECT_FALSE(navigation_state_
.GetErrorOccurredInFrame(main_rfh()));
72 // After an error occurred, no further events should be sent.
73 navigation_state_
.SetErrorOccurredInFrame(main_rfh());
74 EXPECT_FALSE(navigation_state_
.CanSendEvents(main_rfh()));
75 EXPECT_TRUE(navigation_state_
.GetErrorOccurredInFrame(main_rfh()));
77 // Navigations to a network error page should be ignored.
78 navigation_state_
.StartTrackingNavigation(main_rfh(), GURL(), true, false);
79 EXPECT_FALSE(navigation_state_
.CanSendEvents(main_rfh()));
80 EXPECT_TRUE(navigation_state_
.GetErrorOccurredInFrame(main_rfh()));
82 // However, when the frame navigates again, it should send events again.
83 navigation_state_
.StartTrackingNavigation(main_rfh(), url
, false, false);
84 EXPECT_TRUE(navigation_state_
.CanSendEvents(main_rfh()));
85 EXPECT_FALSE(navigation_state_
.GetErrorOccurredInFrame(main_rfh()));
88 // Tests that for a sub frame, no events are send after an error occurred, but
89 // before a new navigation happened in this frame.
90 TEST_F(FrameNavigationStateTest
, ErrorStateFrame
) {
91 const GURL
url("http://www.google.com/");
93 content::RenderFrameHost
* sub_frame
=
94 content::RenderFrameHostTester::For(main_rfh())->AppendChild("child");
95 navigation_state_
.StartTrackingNavigation(main_rfh(), url
, false, false);
96 navigation_state_
.StartTrackingNavigation(sub_frame
, url
, false, false);
97 EXPECT_TRUE(navigation_state_
.CanSendEvents(main_rfh()));
98 EXPECT_TRUE(navigation_state_
.CanSendEvents(sub_frame
));
100 // After an error occurred, no further events should be sent.
101 navigation_state_
.SetErrorOccurredInFrame(sub_frame
);
102 EXPECT_TRUE(navigation_state_
.CanSendEvents(main_rfh()));
103 EXPECT_FALSE(navigation_state_
.CanSendEvents(sub_frame
));
105 // Navigations to a network error page should be ignored.
106 navigation_state_
.StartTrackingNavigation(sub_frame
, GURL(), true, false);
107 EXPECT_TRUE(navigation_state_
.CanSendEvents(main_rfh()));
108 EXPECT_FALSE(navigation_state_
.CanSendEvents(sub_frame
));
110 // However, when the frame navigates again, it should send events again.
111 navigation_state_
.StartTrackingNavigation(sub_frame
, url
, false, false);
112 EXPECT_TRUE(navigation_state_
.CanSendEvents(main_rfh()));
113 EXPECT_TRUE(navigation_state_
.CanSendEvents(sub_frame
));
116 // Tests that no events are send for a not web-safe scheme.
117 TEST_F(FrameNavigationStateTest
, WebSafeScheme
) {
118 const GURL
url("unsafe://www.google.com/");
120 navigation_state_
.StartTrackingNavigation(main_rfh(), url
, false, false);
121 EXPECT_FALSE(navigation_state_
.CanSendEvents(main_rfh()));
124 // Test for <iframe srcdoc=""> frames.
125 TEST_F(FrameNavigationStateTest
, SrcDoc
) {
126 const GURL
url("http://www.google.com/");
127 const GURL
blank("about:blank");
128 const GURL
srcdoc("about:srcdoc");
130 content::RenderFrameHost
* sub_frame
=
131 content::RenderFrameHostTester::For(main_rfh())->AppendChild("child");
132 navigation_state_
.StartTrackingNavigation(main_rfh(), url
, false, false);
133 navigation_state_
.StartTrackingNavigation(sub_frame
, blank
, false, true);
134 EXPECT_TRUE(navigation_state_
.CanSendEvents(main_rfh()));
135 EXPECT_TRUE(navigation_state_
.CanSendEvents(sub_frame
));
137 EXPECT_EQ(url
, navigation_state_
.GetUrl(main_rfh()));
138 EXPECT_EQ(srcdoc
, navigation_state_
.GetUrl(sub_frame
));
140 EXPECT_TRUE(navigation_state_
.IsValidUrl(srcdoc
));
143 // Test that an individual frame can be detached.
144 TEST_F(FrameNavigationStateTest
, DetachFrame
) {
145 const GURL
url1("http://www.google.com/");
146 const GURL
url2("http://mail.google.com/");
148 // Create a main frame.
149 EXPECT_FALSE(navigation_state_
.CanSendEvents(main_rfh()));
150 EXPECT_FALSE(navigation_state_
.IsValidFrame(main_rfh()));
151 navigation_state_
.StartTrackingNavigation(main_rfh(), url1
, false, false);
152 navigation_state_
.SetNavigationCommitted(main_rfh());
153 EXPECT_TRUE(navigation_state_
.CanSendEvents(main_rfh()));
154 EXPECT_TRUE(navigation_state_
.IsValidFrame(main_rfh()));
157 content::RenderFrameHost
* sub_frame
=
158 content::RenderFrameHostTester::For(main_rfh())->AppendChild("child");
159 EXPECT_FALSE(navigation_state_
.CanSendEvents(sub_frame
));
160 EXPECT_FALSE(navigation_state_
.IsValidFrame(sub_frame
));
161 navigation_state_
.StartTrackingNavigation(sub_frame
, url2
, false, false);
162 navigation_state_
.SetNavigationCommitted(sub_frame
);
163 EXPECT_TRUE(navigation_state_
.CanSendEvents(sub_frame
));
164 EXPECT_TRUE(navigation_state_
.IsValidFrame(sub_frame
));
166 // Check frame state.
167 EXPECT_EQ(url1
, navigation_state_
.GetUrl(main_rfh()));
168 EXPECT_EQ(url2
, navigation_state_
.GetUrl(sub_frame
));
171 navigation_state_
.FrameHostDeleted(sub_frame
);
172 EXPECT_EQ(url1
, navigation_state_
.GetUrl(main_rfh()));
173 EXPECT_FALSE(navigation_state_
.CanSendEvents(sub_frame
));
174 EXPECT_FALSE(navigation_state_
.IsValidFrame(sub_frame
));
177 } // namespace extensions