1 // Copyright (c) 2013 Intel Corporation. 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/command_line.h"
6 #include "base/files/file_path.h"
7 #include "base/file_util.h"
8 #include "base/path_service.h"
9 #include "base/process/launch.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "xwalk/runtime/browser/image_util.h"
14 #include "xwalk/runtime/browser/runtime.h"
15 #include "xwalk/runtime/browser/runtime_ui_strategy.h"
16 #include "xwalk/runtime/common/xwalk_notification_types.h"
17 #include "xwalk/test/base/in_process_browser_test.h"
18 #include "xwalk/test/base/xwalk_test_utils.h"
19 #include "content/public/browser/navigation_controller.h"
20 #include "content/public/browser/navigation_entry.h"
21 #include "content/public/browser/notification_details.h"
22 #include "content/public/browser/notification_observer.h"
23 #include "content/public/browser/notification_registrar.h"
24 #include "content/public/browser/notification_service.h"
25 #include "content/public/browser/notification_source.h"
26 #include "content/public/browser/render_view_host.h"
27 #include "content/public/browser/web_contents.h"
28 #include "content/public/test/browser_test_utils.h"
29 #include "content/public/test/test_utils.h"
30 #include "net/base/net_util.h"
31 #include "testing/gmock/include/gmock/gmock.h"
34 #include "ui/aura/window.h"
37 using xwalk::NativeAppWindow;
39 using content::WebContents;
43 Runtime* CreateWithDefaultWindow(
44 xwalk::RuntimeContext* runtime_context, const GURL& url,
45 Runtime::Observer* observer = NULL) {
46 Runtime* runtime = Runtime::Create(runtime_context, observer);
47 runtime->LoadURL(url);
48 #if !defined(OS_ANDROID)
49 xwalk::RuntimeUIStrategy ui_strategy;
50 xwalk::NativeAppWindow::CreateParams params;
51 ui_strategy.Show(runtime, params);
57 // Observer for NOTIFICATION_FULLSCREEN_CHANGED notifications.
58 class FullscreenNotificationObserver
59 : public content::WindowedNotificationObserver {
61 FullscreenNotificationObserver() : WindowedNotificationObserver(
62 xwalk::NOTIFICATION_FULLSCREEN_CHANGED,
63 content::NotificationService::AllSources()) {}
65 DISALLOW_COPY_AND_ASSIGN(FullscreenNotificationObserver);
68 class XWalkRuntimeTest : public InProcessBrowserTest {
71 virtual ~XWalkRuntimeTest() {
72 original_runtimes_.clear();
73 notification_observer_.reset();
76 void Relaunch(const CommandLine& new_command_line) {
77 base::LaunchProcess(new_command_line, base::LaunchOptions(), NULL);
80 // SetUpOnMainThread is called after BrowserMainRunner was initialized and
81 // just before RunTestOnMainThread (aka. TestBody).
82 virtual void SetUpOnMainThread() OVERRIDE {
83 notification_observer_.reset(
84 new content::WindowedNotificationObserver(
85 xwalk::NOTIFICATION_RUNTIME_OPENED,
86 content::NotificationService::AllSources()));
87 original_runtimes_.assign(runtimes().begin(), runtimes().end());
90 // Block UI thread until a new Runtime instance is created.
91 Runtime* WaitForSingleNewRuntime() {
92 notification_observer_->Wait();
93 const RuntimeList& runtime_list = runtimes();
94 for (RuntimeList::const_iterator it = runtime_list.begin();
95 it != runtime_list.end(); ++it) {
96 RuntimeList::iterator target =
97 std::find(original_runtimes_.begin(), original_runtimes_.end(), *it);
98 // Not found means a new one.
99 if (target == original_runtimes_.end()) {
100 original_runtimes_.push_back(*it);
108 RuntimeList original_runtimes_;
109 scoped_ptr<content::WindowedNotificationObserver> notification_observer_;
112 // FIXME(hmin): Since currently the browser process is not shared by multiple
113 // app launch, this test is disabled to avoid floody launches.
114 IN_PROC_BROWSER_TEST_F(XWalkRuntimeTest, DISABLED_SecondLaunch) {
115 Relaunch(GetCommandLineForRelaunch());
117 Runtime* second_runtime = NULL;
118 EXPECT_TRUE(second_runtime == WaitForSingleNewRuntime());
119 ASSERT_EQ(2u, runtimes().size());
122 IN_PROC_BROWSER_TEST_F(XWalkRuntimeTest, CreateAndCloseRuntime) {
123 size_t len = runtimes().size();
126 // Create a new Runtime instance.
127 GURL url(test_server()->GetURL("test.html"));
128 Runtime* new_runtime = CreateWithDefaultWindow(
129 GetRuntimeContext(), url, runtime_registry());
130 EXPECT_TRUE(url == new_runtime->web_contents()->GetURL());
131 EXPECT_EQ(new_runtime, WaitForSingleNewRuntime());
132 content::RunAllPendingInMessageLoop();
133 EXPECT_EQ(len + 1, runtimes().size());
135 // Close the newly created Runtime instance.
136 new_runtime->Close();
137 content::RunAllPendingInMessageLoop();
138 EXPECT_EQ(len, runtimes().size());
141 IN_PROC_BROWSER_TEST_F(XWalkRuntimeTest, LoadURLAndClose) {
142 GURL url(test_server()->GetURL("test.html"));
143 size_t len = runtimes().size();
144 runtime()->LoadURL(url);
145 content::RunAllPendingInMessageLoop();
146 EXPECT_EQ(len, runtimes().size());
148 content::RunAllPendingInMessageLoop();
149 EXPECT_EQ(len - 1, runtimes().size());
152 IN_PROC_BROWSER_TEST_F(XWalkRuntimeTest, CloseNativeWindow) {
153 GURL url(test_server()->GetURL("test.html"));
154 Runtime* new_runtime = CreateWithDefaultWindow(
155 GetRuntimeContext(), url, runtime_registry());
156 size_t len = runtimes().size();
157 new_runtime->window()->Close();
158 content::RunAllPendingInMessageLoop();
159 // Closing native window will lead to close Runtime instance.
160 EXPECT_EQ(len - 1, runtimes().size());
163 IN_PROC_BROWSER_TEST_F(XWalkRuntimeTest, LaunchWithFullscreenWindow) {
164 GURL url(test_server()->GetURL("test.html"));
165 Runtime* new_runtime = Runtime::Create(
166 GetRuntimeContext(), runtime_registry());
168 NativeAppWindow::CreateParams params;
169 params.state = ui::SHOW_STATE_FULLSCREEN;
170 scoped_ptr<xwalk::RuntimeUIStrategy> ui_strategy(
171 new xwalk::RuntimeUIStrategy);
172 ui_strategy->Show(new_runtime, params);
173 xwalk_test_utils::NavigateToURL(new_runtime, url);
175 EXPECT_TRUE(new_runtime->window()->IsFullscreen());
178 IN_PROC_BROWSER_TEST_F(XWalkRuntimeTest, HTML5FullscreenAPI) {
179 size_t len = runtimes().size();
180 GURL url = xwalk_test_utils::GetTestURL(
181 base::FilePath(), base::FilePath().AppendASCII("fullscreen.html"));
182 xwalk_test_utils::NavigateToURL(runtime(), url);
183 EXPECT_TRUE(false == runtime()->window()->IsFullscreen());
185 FullscreenNotificationObserver enter_observer;
186 bool ret = content::ExecuteScript(
187 runtime()->web_contents(), "doFullscreenClick();");
189 content::RunAllPendingInMessageLoop();
190 enter_observer.Wait();
191 // Calling doFullscreenClick defined in fullscreen.html leads to enter into
192 // fullscreen window state, so it's expected to be fullscreen.
193 EXPECT_TRUE(true == runtime()->window()->IsFullscreen());
195 FullscreenNotificationObserver exit_observer;
196 ret = content::ExecuteScript(
197 runtime()->web_contents(), "doExitFullscreenClick();");
199 content::RunAllPendingInMessageLoop();
200 exit_observer.Wait();
201 // Calling doExitFullscreenClick defined in fullscreen.html leads to exit
202 // fullscreen window state, so it's expected to be not fullscreen.
203 EXPECT_TRUE(false == runtime()->window()->IsFullscreen());
207 #if !defined(OS_MACOSX)
208 IN_PROC_BROWSER_TEST_F(XWalkRuntimeTest, GetWindowTitle) {
209 GURL url = xwalk_test_utils::GetTestURL(
210 base::FilePath(), base::FilePath().AppendASCII("title.html"));
211 base::string16 title = base::ASCIIToUTF16("Dummy Title");
212 content::TitleWatcher title_watcher(runtime()->web_contents(), title);
213 xwalk_test_utils::NavigateToURL(runtime(), url);
214 EXPECT_EQ(title, title_watcher.WaitAndGetTitle());
216 NativeAppWindow* window = runtime()->window();
217 base::string16 window_title = window->GetNativeWindow()->title();
218 EXPECT_EQ(title, window_title);
222 IN_PROC_BROWSER_TEST_F(XWalkRuntimeTest, OpenLinkInNewRuntime) {
223 size_t len = runtimes().size();
224 GURL url = xwalk_test_utils::GetTestURL(
225 base::FilePath(), base::FilePath().AppendASCII("new_target.html"));
226 xwalk_test_utils::NavigateToURL(runtime(), url);
227 bool ret = content::ExecuteScript(runtime()->web_contents(), "doClick();");
229 content::RunAllPendingInMessageLoop();
230 // Calling doClick defined in new_target.html leads to open a href in a new
231 // target window, and so it is expected to create a new Runtime instance.
232 Runtime* second = WaitForSingleNewRuntime();
233 EXPECT_TRUE(NULL != second);
234 EXPECT_NE(runtime(), second);
235 EXPECT_EQ(len + 1, runtimes().size());
238 #if defined(OS_TIZEN)
239 IN_PROC_BROWSER_TEST_F(XWalkRuntimeTest, LoadTizenWebUiFwFile) {
240 GURL url = xwalk_test_utils::GetTestURL(
241 base::FilePath(), base::FilePath().AppendASCII("tizenwebuifw.html"));
242 base::string16 title = base::ASCIIToUTF16("Pass");
243 content::TitleWatcher title_watcher(runtime()->web_contents(), title);
244 xwalk_test_utils::NavigateToURL(runtime(), url);
245 EXPECT_EQ(title, title_watcher.WaitAndGetTitle());