Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / content / browser / web_contents / opened_by_dom_browsertest.cc
1 // Copyright 2014 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.
4
5 #include "base/command_line.h"
6 #include "base/strings/stringprintf.h"
7 #include "content/public/browser/web_contents.h"
8 #include "content/public/browser/web_contents_delegate.h"
9 #include "content/public/common/content_switches.h"
10 #include "content/public/test/browser_test_utils.h"
11 #include "content/public/test/content_browser_test.h"
12 #include "content/public/test/content_browser_test_utils.h"
13 #include "content/public/test/test_navigation_observer.h"
14 #include "content/shell/browser/shell.h"
15 #include "net/dns/mock_host_resolver.h"
16 #include "url/gurl.h"
17
18 namespace content {
19
20 namespace {
21
22 // A dummy WebContentsDelegate which tracks whether CloseContents() has been
23 // called. It refuses the actual close but keeps track of whether the renderer
24 // requested it.
25 class CloseTrackingDelegate : public WebContentsDelegate {
26  public:
27   CloseTrackingDelegate() : close_contents_called_(false) {}
28
29   bool close_contents_called() const { return close_contents_called_; }
30
31   void CloseContents(WebContents* source) override {
32     close_contents_called_ = true;
33   }
34
35  private:
36   bool close_contents_called_;
37
38   DISALLOW_COPY_AND_ASSIGN(CloseTrackingDelegate);
39 };
40
41 }  // namespace
42
43 class OpenedByDOMTest : public ContentBrowserTest {
44  protected:
45   void SetUpCommandLine(CommandLine* command_line) override {
46     // Use --site-per-process to force process swaps on cross-site navigations.
47     command_line->AppendSwitch(switches::kSitePerProcess);
48   }
49
50   bool AttemptCloseFromJavaScript(WebContents* web_contents) {
51     CloseTrackingDelegate close_tracking_delegate;
52     WebContentsDelegate* old_delegate = web_contents->GetDelegate();
53     web_contents->SetDelegate(&close_tracking_delegate);
54
55     const char kCloseWindowScript[] =
56         // Close the window.
57         "window.close();"
58         // Report back after an event loop iteration; the close IPC isn't sent
59         // immediately.
60         "setTimeout(function() {"
61         "window.domAutomationController.send(0);"
62         "});";
63     int dummy;
64     CHECK(ExecuteScriptAndExtractInt(web_contents, kCloseWindowScript, &dummy));
65
66     web_contents->SetDelegate(old_delegate);
67     return close_tracking_delegate.close_contents_called();
68   }
69
70   Shell* OpenWindowFromJavaScript(Shell* shell, const GURL& url) {
71     // Wait for the popup to be created and for it to have navigated.
72     ShellAddedObserver new_shell_observer;
73     TestNavigationObserver nav_observer(NULL);
74     nav_observer.StartWatchingNewWebContents();
75     CHECK(ExecuteScript(
76         shell->web_contents(),
77         base::StringPrintf("window.open('%s')", url.spec().c_str())));
78     nav_observer.Wait();
79     return new_shell_observer.GetShell();
80   }
81 };
82
83 // Tests that window.close() does not work on a normal window that has navigated
84 // a few times.
85 IN_PROC_BROWSER_TEST_F(OpenedByDOMTest, NormalWindow) {
86   ASSERT_TRUE(test_server()->Start());
87
88   // window.close is allowed if the window was opened by DOM OR the back/forward
89   // list has only one element. Navigate a bit so the second condition is false.
90   GURL url1 = test_server()->GetURL("files/site_isolation/blank.html?1");
91   GURL url2 = test_server()->GetURL("files/site_isolation/blank.html?2");
92   NavigateToURL(shell(), url1);
93   NavigateToURL(shell(), url2);
94
95   // This window was not opened by DOM, so close does not reach the browser
96   // process.
97   EXPECT_FALSE(AttemptCloseFromJavaScript(shell()->web_contents()));
98 }
99
100 // Tests that window.close() works in a popup window that has navigated a few
101 // times.
102 IN_PROC_BROWSER_TEST_F(OpenedByDOMTest, Popup) {
103   ASSERT_TRUE(test_server()->Start());
104
105   GURL url1 = test_server()->GetURL("files/site_isolation/blank.html?1");
106   GURL url2 = test_server()->GetURL("files/site_isolation/blank.html?2");
107   GURL url3 = test_server()->GetURL("files/site_isolation/blank.html?3");
108   NavigateToURL(shell(), url1);
109
110   Shell* popup = OpenWindowFromJavaScript(shell(), url2);
111   NavigateToURL(popup, url3);
112   EXPECT_TRUE(AttemptCloseFromJavaScript(popup->web_contents()));
113 }
114
115 // Tests that window.close() works in a popup window that has navigated a few
116 // times and swapped processes.
117 // Crashes on all platforms. http://crbug.com/399709
118 IN_PROC_BROWSER_TEST_F(OpenedByDOMTest, DISABLED_CrossProcessPopup) {
119   host_resolver()->AddRule("*", "127.0.0.1");
120   ASSERT_TRUE(test_server()->Start());
121
122   GURL url1 = test_server()->GetURL("files/site_isolation/blank.html?1");
123
124   GURL url2 = test_server()->GetURL("files/site_isolation/blank.html?2");
125   GURL::Replacements replace_host;
126   std::string foo_com("foo.com");
127   replace_host.SetHostStr(foo_com);
128   url2 = url2.ReplaceComponents(replace_host);
129
130   GURL url3 = test_server()->GetURL("files/site_isolation/blank.html?3");
131   url3 = url3.ReplaceComponents(replace_host);
132
133   NavigateToURL(shell(), url1);
134
135   Shell* popup = OpenWindowFromJavaScript(shell(), url2);
136   NavigateToURL(popup, url3);
137   EXPECT_TRUE(AttemptCloseFromJavaScript(popup->web_contents()));
138 }
139
140 }  // namespace content