Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(223)

Side by Side Diff: components/html_viewer/html_frame_apptest.cc

Issue 1239313004: More html_viewer OOPIF changes (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix compile Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « components/html_viewer/frame_tree_manager.cc ('k') | components/html_viewer/html_viewer.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/bind.h" 5 #include "base/bind.h"
6 #include "base/command_line.h" 6 #include "base/command_line.h"
7 #include "base/json/json_reader.h"
7 #include "base/run_loop.h" 8 #include "base/run_loop.h"
8 #include "base/strings/stringprintf.h" 9 #include "base/strings/stringprintf.h"
9 #include "base/test/test_timeouts.h" 10 #include "base/test/test_timeouts.h"
11 #include "base/values.h"
10 #include "components/html_viewer/public/interfaces/test_html_viewer.mojom.h" 12 #include "components/html_viewer/public/interfaces/test_html_viewer.mojom.h"
11 #include "components/view_manager/public/cpp/tests/view_manager_test_base.h" 13 #include "components/view_manager/public/cpp/tests/view_manager_test_base.h"
12 #include "components/view_manager/public/cpp/view.h" 14 #include "components/view_manager/public/cpp/view.h"
13 #include "components/view_manager/public/cpp/view_manager.h" 15 #include "components/view_manager/public/cpp/view_manager.h"
14 #include "mandoline/tab/frame.h" 16 #include "mandoline/tab/frame.h"
15 #include "mandoline/tab/frame_connection.h" 17 #include "mandoline/tab/frame_connection.h"
16 #include "mandoline/tab/frame_tree.h" 18 #include "mandoline/tab/frame_tree.h"
17 #include "mandoline/tab/public/interfaces/frame_tree.mojom.h" 19 #include "mandoline/tab/public/interfaces/frame_tree.mojom.h"
18 #include "mojo/application/public/cpp/application_impl.h" 20 #include "mojo/application/public/cpp/application_impl.h"
19 #include "net/test/spawned_test_server/spawned_test_server.h" 21 #include "net/test/spawned_test_server/spawned_test_server.h"
20 #include "third_party/mojo_services/src/accessibility/public/interfaces/accessib ility.mojom.h" 22 #include "third_party/mojo_services/src/accessibility/public/interfaces/accessib ility.mojom.h"
21 23
22 using mandoline::Frame; 24 using mandoline::Frame;
23 using mandoline::FrameConnection; 25 using mandoline::FrameConnection;
24 using mandoline::FrameTree; 26 using mandoline::FrameTree;
25 using mandoline::FrameTreeClient; 27 using mandoline::FrameTreeClient;
26 28
27 namespace mojo { 29 namespace mojo {
28 30
29 namespace { 31 namespace {
30 32
31 // Switch to enable out of process iframes. 33 // Switch to enable out of process iframes.
32 const char kOOPIF[] = "oopifs"; 34 const char kOOPIF[] = "oopifs";
33 35
36 const char kAddFrameWithEmptyPageScript[] =
37 "var iframe = document.createElement(\"iframe\");"
38 "iframe.src = \"http://127.0.0.1:%u/files/empty_page.html\";"
39 "document.body.appendChild(iframe);";
40
34 bool EnableOOPIFs() { 41 bool EnableOOPIFs() {
35 return base::CommandLine::ForCurrentProcess()->HasSwitch(kOOPIF); 42 return base::CommandLine::ForCurrentProcess()->HasSwitch(kOOPIF);
36 } 43 }
37 44
45 mojo::ApplicationConnection* ApplicationConnectionForFrame(Frame* frame) {
46 return static_cast<FrameConnection*>(frame->user_data())
47 ->application_connection();
48 }
49
38 std::string GetFrameText(ApplicationConnection* connection) { 50 std::string GetFrameText(ApplicationConnection* connection) {
39 html_viewer::TestHTMLViewerPtr test_html_viewer; 51 html_viewer::TestHTMLViewerPtr test_html_viewer;
40 connection->ConnectToService(&test_html_viewer); 52 connection->ConnectToService(&test_html_viewer);
41 std::string result; 53 std::string result;
42 test_html_viewer->GetContentAsText( 54 test_html_viewer->GetContentAsText([&result](const String& mojo_string) {
43 [&result](const String& mojo_string) { result = mojo_string; }); 55 result = mojo_string;
44 test_html_viewer.WaitForIncomingResponse(); 56 ASSERT_TRUE(ViewManagerTestBase::QuitRunLoop());
57 });
58 if (!ViewManagerTestBase::DoRunLoopWithTimeout())
59 ADD_FAILURE() << "Timed out waiting for execute to complete";
60 // test_html_viewer.WaitForIncomingResponse();
45 return result; 61 return result;
46 } 62 }
47 63
64 scoped_ptr<base::Value> ExecuteScript(ApplicationConnection* connection,
65 const std::string& script) {
66 html_viewer::TestHTMLViewerPtr test_html_viewer;
67 connection->ConnectToService(&test_html_viewer);
68 scoped_ptr<base::Value> result;
69 test_html_viewer->ExecuteScript(script, [&result](const String& json_string) {
70 result = base::JSONReader::Read(json_string.To<std::string>());
71 ASSERT_TRUE(ViewManagerTestBase::QuitRunLoop());
72 });
73 if (!ViewManagerTestBase::DoRunLoopWithTimeout())
74 ADD_FAILURE() << "Timed out waiting for execute to complete";
75 return result.Pass();
76 }
77
48 } // namespace 78 } // namespace
49 79
50 class HTMLFrameTest : public ViewManagerTestBase { 80 class HTMLFrameTest : public ViewManagerTestBase {
51 public: 81 public:
52 HTMLFrameTest() {} 82 HTMLFrameTest() {}
53 ~HTMLFrameTest() override {} 83 ~HTMLFrameTest() override {}
54 84
55 protected: 85 protected:
86 Frame* LoadEmptyPageAndCreateFrame() {
87 View* embed_view = window_manager()->CreateView();
88 FrameConnection* root_connection =
89 InitFrameTree(embed_view, "http://127.0.0.1:%u/files/empty_page.html");
90 const std::string frame_text =
91 GetFrameText(root_connection->application_connection());
92 if (frame_text != "child") {
93 ADD_FAILURE() << "unexpected text " << frame_text;
94 return nullptr;
95 }
96
97 // Dynamically add a new frame.
98 ExecuteScript(root_connection->application_connection(),
99 AddPortToString(kAddFrameWithEmptyPageScript));
100
101 // Wait for the frame to appear.
102 if (frame_tree_->root()->children().empty() &&
103 !WaitForEmbedForDescendant()) {
104 ADD_FAILURE() << "timed out waiting for child";
105 return nullptr;
106 }
107
108 if (embed_view->children().size() != 1u) {
109 ADD_FAILURE() << "unexpected number of children "
110 << embed_view->children().size();
111 return nullptr;
112 }
113 return frame_tree_->root()->FindFrame(embed_view->children()[0]->id());
114 }
115
116 std::string AddPortToString(const std::string& string) {
117 const uint16_t assigned_port = http_server_->host_port_pair().port();
118 return base::StringPrintf(string.c_str(), assigned_port);
119 }
120
56 mojo::URLRequestPtr BuildRequestForURL(const std::string& url_string) { 121 mojo::URLRequestPtr BuildRequestForURL(const std::string& url_string) {
57 const uint16_t assigned_port = http_server_->host_port_pair().port();
58 mojo::URLRequestPtr request(mojo::URLRequest::New()); 122 mojo::URLRequestPtr request(mojo::URLRequest::New());
59 request->url = mojo::String::From( 123 request->url = mojo::String::From(AddPortToString(url_string));
60 base::StringPrintf(url_string.c_str(), assigned_port));
61 return request.Pass(); 124 return request.Pass();
62 } 125 }
63 126
64 FrameConnection* InitFrameTree(View* view, const std::string& url_string) { 127 FrameConnection* InitFrameTree(View* view, const std::string& url_string) {
65 scoped_ptr<FrameConnection> frame_connection(new FrameConnection); 128 scoped_ptr<FrameConnection> frame_connection(new FrameConnection);
66 FrameConnection* result = frame_connection.get(); 129 FrameConnection* result = frame_connection.get();
67 ViewManagerClientPtr view_manager_client; 130 ViewManagerClientPtr view_manager_client;
68 frame_connection->Init(application_impl(), BuildRequestForURL(url_string), 131 frame_connection->Init(application_impl(), BuildRequestForURL(url_string),
69 &view_manager_client); 132 &view_manager_client);
70 FrameTreeClient* frame_tree_client = frame_connection->frame_tree_client(); 133 FrameTreeClient* frame_tree_client = frame_connection->frame_tree_client();
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 182
120 private: 183 private:
121 // A runloop specifically for OnEmbedForDescendant(). We use a separate 184 // A runloop specifically for OnEmbedForDescendant(). We use a separate
122 // runloop here as it's possible at the time OnEmbedForDescendant() is invoked 185 // runloop here as it's possible at the time OnEmbedForDescendant() is invoked
123 // a separate RunLoop is already running that we shouldn't quit. 186 // a separate RunLoop is already running that we shouldn't quit.
124 scoped_ptr<base::RunLoop> embed_run_loop_; 187 scoped_ptr<base::RunLoop> embed_run_loop_;
125 188
126 DISALLOW_COPY_AND_ASSIGN(HTMLFrameTest); 189 DISALLOW_COPY_AND_ASSIGN(HTMLFrameTest);
127 }; 190 };
128 191
129 TEST_F(HTMLFrameTest, HelloWorld) { 192 TEST_F(HTMLFrameTest, PageWithSingleFrame) {
130 if (!EnableOOPIFs()) 193 if (!EnableOOPIFs())
131 return; 194 return;
132 195
133 View* embed_view = window_manager()->CreateView(); 196 View* embed_view = window_manager()->CreateView();
134 197
135 FrameConnection* root_connection = InitFrameTree( 198 FrameConnection* root_connection = InitFrameTree(
136 embed_view, "http://127.0.0.1:%u/files/page_with_single_frame.html"); 199 embed_view, "http://127.0.0.1:%u/files/page_with_single_frame.html");
137 200
138 ASSERT_EQ("Page with single frame", 201 ASSERT_EQ("Page with single frame",
139 GetFrameText(root_connection->application_connection())); 202 GetFrameText(root_connection->application_connection()));
140 203
141 // page_with_single_frame contains a child frame. The child frame should 204 // page_with_single_frame contains a child frame. The child frame should
142 // create 205 // create a new View and Frame.
143 // a new View and Frame. 206 if (frame_tree_->root()->children().empty())
144 if (embed_view->children().empty())
145 ASSERT_TRUE(WaitForEmbedForDescendant()); 207 ASSERT_TRUE(WaitForEmbedForDescendant());
146 208
147 ASSERT_EQ(1u, embed_view->children().size()); 209 ASSERT_EQ(1u, embed_view->children().size());
148 Frame* child_frame = 210 Frame* child_frame =
149 frame_tree_->root()->FindFrame(embed_view->children()[0]->id()); 211 frame_tree_->root()->FindFrame(embed_view->children()[0]->id());
150 ASSERT_TRUE(child_frame); 212 ASSERT_TRUE(child_frame);
151 213
152 ASSERT_EQ("child", 214 ASSERT_EQ("child",
153 GetFrameText(static_cast<FrameConnection*>(child_frame->user_data()) 215 GetFrameText(static_cast<FrameConnection*>(child_frame->user_data())
154 ->application_connection())); 216 ->application_connection()));
155 } 217 }
156 218
219 namespace {} // namespace
220
221 TEST_F(HTMLFrameTest, DynamicallyAddFrameAndVerifyParent) {
222 if (!EnableOOPIFs())
223 return;
224
225 Frame* child_frame = LoadEmptyPageAndCreateFrame();
226 ASSERT_TRUE(child_frame);
227
228 mojo::ApplicationConnection* child_frame_connection =
229 ApplicationConnectionForFrame(child_frame);
230
231 ASSERT_EQ("child", GetFrameText(child_frame_connection));
232 // The child's parent should not be itself:
233 const char kGetWindowParentNameScript[] =
234 "window.parent == window ? 'parent is self' : 'parent not self';";
235 scoped_ptr<base::Value> parent_value(
236 ExecuteScript(child_frame_connection, kGetWindowParentNameScript));
237 ASSERT_TRUE(parent_value->IsType(base::Value::TYPE_LIST));
238 base::ListValue* parent_list;
239 ASSERT_TRUE(parent_value->GetAsList(&parent_list));
240 ASSERT_EQ(1u, parent_list->GetSize());
241 std::string parent_name;
242 ASSERT_TRUE(parent_list->GetString(0u, &parent_name));
243 EXPECT_EQ("parent not self", parent_name);
244 }
245
246 TEST_F(HTMLFrameTest, DynamicallyAddFrameAndSeeNameChange) {
247 if (!EnableOOPIFs())
248 return;
249
250 Frame* child_frame = LoadEmptyPageAndCreateFrame();
251 ASSERT_TRUE(child_frame);
252
253 mojo::ApplicationConnection* child_frame_connection =
254 ApplicationConnectionForFrame(child_frame);
255
256 // Change the name of the child's window.
257 ExecuteScript(child_frame_connection, "window.name = 'new_child';");
258
259 // Eventually the parent should see the change. There is no convenient way
260 // to observer this change, so we repeatedly ask for it and timeout if we
261 // never get the right value.
262 const base::TimeTicks start_time(base::TimeTicks::Now());
263 std::string find_window_result;
264 do {
265 scoped_ptr<base::Value> script_value(
266 ExecuteScript(ApplicationConnectionForFrame(frame_tree_->root()),
267 "window.frames['new_child'] != null ? 'found frame' : "
268 "'unable to find frame';"));
269 if (script_value->IsType(base::Value::TYPE_LIST)) {
270 base::ListValue* script_value_as_list;
271 if (script_value->GetAsList(&script_value_as_list) &&
272 script_value_as_list->GetSize() == 1) {
273 script_value_as_list->GetString(0u, &find_window_result);
274 }
275 }
276 } while (find_window_result != "found frame" &&
277 base::TimeTicks::Now() - start_time <
278 TestTimeouts::action_timeout());
279 EXPECT_EQ("found frame", find_window_result);
280 }
281
157 } // namespace mojo 282 } // namespace mojo
OLDNEW
« no previous file with comments | « components/html_viewer/frame_tree_manager.cc ('k') | components/html_viewer/html_viewer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698