[M120][Tizen][Onscreen] Fix build errors for TV profile
[platform/framework/web/chromium-efl.git] / chrome / browser / no_best_effort_tasks_browsertest.cc
1 // Copyright 2018 The Chromium Authors
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/base_switches.h"
6 #include "base/command_line.h"
7 #include "base/files/file_path.h"
8 #include "base/path_service.h"
9 #include "base/run_loop.h"
10 #include "base/strings/string_piece.h"
11 #include "base/strings/stringprintf.h"
12 #include "base/task/sequenced_task_runner.h"
13 #include "build/build_config.h"
14 #include "build/buildflag.h"
15 #include "chrome/browser/chrome_content_browser_client.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/ui/browser.h"
18 #include "chrome/browser/ui/tabs/tab_strip_model.h"
19 #include "chrome/common/chrome_paths.h"
20 #include "chrome/test/base/in_process_browser_test.h"
21 #include "chrome/test/base/ui_test_utils.h"
22 #include "content/public/browser/web_contents.h"
23 #include "content/public/browser/web_contents_observer.h"
24 #include "content/public/test/browser_test.h"
25 #include "content/public/test/browser_test_utils.h"
26 #include "content/public/test/test_utils.h"
27 #include "net/dns/mock_host_resolver.h"
28 #include "testing/gtest/include/gtest/gtest.h"
29 #include "url/url_constants.h"
30
31 #if BUILDFLAG(ENABLE_EXTENSIONS)
32 #include "chrome/browser/extensions/unpacked_installer.h"
33 #include "extensions/browser/extension_registry.h"
34 #include "extensions/browser/extension_system.h"
35 #include "extensions/browser/test_extension_registry_observer.h"
36 #include "extensions/common/extension.h"
37 #endif
38
39 namespace {
40
41 class RunLoopUntilLoadedAndPainted : public content::WebContentsObserver {
42  public:
43   explicit RunLoopUntilLoadedAndPainted(content::WebContents* web_contents)
44       : content::WebContentsObserver(web_contents) {}
45
46   RunLoopUntilLoadedAndPainted(const RunLoopUntilLoadedAndPainted&) = delete;
47   RunLoopUntilLoadedAndPainted& operator=(const RunLoopUntilLoadedAndPainted&) =
48       delete;
49
50   ~RunLoopUntilLoadedAndPainted() override = default;
51
52   // Runs a RunLoop on the main thread until the first non-empty frame is
53   // painted and the load is complete for the WebContents provided to the
54   // constructor.
55   void Run() {
56     if (LoadedAndPainted())
57       return;
58
59     run_loop_.Run();
60   }
61
62  private:
63   bool LoadedAndPainted() {
64     return web_contents()->CompletedFirstVisuallyNonEmptyPaint() &&
65            !web_contents()->IsLoading();
66   }
67
68   // content::WebContentsObserver:
69   void DidFirstVisuallyNonEmptyPaint() override {
70     if (LoadedAndPainted())
71       run_loop_.Quit();
72   }
73   void DidStopLoading() override {
74     if (LoadedAndPainted())
75       run_loop_.Quit();
76   }
77
78   base::RunLoop run_loop_;
79 };
80
81 class NoBestEffortTasksTest : public InProcessBrowserTest {
82  public:
83   NoBestEffortTasksTest(const NoBestEffortTasksTest&) = delete;
84   NoBestEffortTasksTest& operator=(const NoBestEffortTasksTest&) = delete;
85
86  protected:
87   NoBestEffortTasksTest() = default;
88   ~NoBestEffortTasksTest() override = default;
89
90  private:
91   void SetUpCommandLine(base::CommandLine* command_line) override {
92     command_line->AppendSwitch(switches::kDisableBestEffortTasks);
93   }
94
95   void SetUpOnMainThread() override {
96     // Redirect all DNS requests back to localhost (to the embedded test
97     // server).
98     host_resolver()->AddRule("*", "127.0.0.1");
99     InProcessBrowserTest::SetUpOnMainThread();
100   }
101 };
102
103 #if BUILDFLAG(ENABLE_EXTENSIONS)
104 constexpr base::StringPiece kExtensionId = "ddchlicdkolnonkihahngkmmmjnjlkkf";
105 constexpr base::TimeDelta kSendMessageRetryPeriod = base::Milliseconds(250);
106 #endif
107
108 }  // namespace
109
110 // Verify that it is possible to load and paint the initial about:blank page
111 // without running BEST_EFFORT tasks.
112 // TODO(https://crbug.com/1484434): Disabled due to excessive flakiness.
113 IN_PROC_BROWSER_TEST_F(NoBestEffortTasksTest, DISABLED_LoadAndPaintAboutBlank) {
114   content::WebContents* const web_contents =
115       browser()->tab_strip_model()->GetActiveWebContents();
116   EXPECT_TRUE(web_contents->GetLastCommittedURL().IsAboutBlank());
117
118   RunLoopUntilLoadedAndPainted run_until_loaded_and_painted(web_contents);
119   run_until_loaded_and_painted.Run();
120 }
121
122 // Verify that it is possible to load and paint a page from the network without
123 // running BEST_EFFORT tasks.
124 //
125 // This test has more dependencies than LoadAndPaintAboutBlank, including
126 // loading cookies.
127 // TODO(https://crbug.com/1484434): Disabled due to excessive flakiness.
128 IN_PROC_BROWSER_TEST_F(NoBestEffortTasksTest,
129                        DISABLED_LoadAndPaintFromNetwork) {
130   ASSERT_TRUE(embedded_test_server()->Start());
131
132   content::OpenURLParams open(
133       embedded_test_server()->GetURL("a.com", "/empty.html"),
134       content::Referrer(), WindowOpenDisposition::NEW_FOREGROUND_TAB,
135       ui::PAGE_TRANSITION_TYPED, false);
136   content::WebContents* const web_contents = browser()->OpenURL(open);
137   EXPECT_TRUE(web_contents->IsLoading());
138
139   RunLoopUntilLoadedAndPainted run_until_loaded_and_painted(web_contents);
140   run_until_loaded_and_painted.Run();
141 }
142
143 // Verify that it is possible to load and paint a file:// URL without running
144 // BEST_EFFORT tasks. Regression test for https://crbug.com/973244.
145 // TODO(https://crbug.com/1484434): Disabled due to excessive flakiness.
146 IN_PROC_BROWSER_TEST_F(NoBestEffortTasksTest, DISABLED_LoadAndPaintFileScheme) {
147   constexpr base::FilePath::CharType kFile[] = FILE_PATH_LITERAL("links.html");
148   GURL file_url(ui_test_utils::GetTestUrl(
149       base::FilePath(base::FilePath::kCurrentDirectory),
150       base::FilePath(kFile)));
151   ASSERT_TRUE(file_url.SchemeIs(url::kFileScheme));
152
153   content::OpenURLParams open(file_url, content::Referrer(),
154                               WindowOpenDisposition::NEW_FOREGROUND_TAB,
155                               ui::PAGE_TRANSITION_TYPED, false);
156   content::WebContents* const web_contents = browser()->OpenURL(open);
157   EXPECT_TRUE(web_contents->IsLoading());
158
159   RunLoopUntilLoadedAndPainted run_until_loaded_and_painted(web_contents);
160   run_until_loaded_and_painted.Run();
161 }
162
163 // Verify that an extension can be loaded and perform basic messaging without
164 // running BEST_EFFORT tasks. Regression test for http://crbug.com/177163#c112.
165 //
166 // NOTE: If this test times out, it might help to look at how
167 // http://crbug.com/924416 was resolved.
168 #if BUILDFLAG(ENABLE_EXTENSIONS)
169 IN_PROC_BROWSER_TEST_F(NoBestEffortTasksTest, LoadExtensionAndSendMessages) {
170   ASSERT_TRUE(embedded_test_server()->Start());
171
172   // Load the extension, waiting until the ExtensionRegistry reports that its
173   // renderer has been started.
174   base::FilePath extension_dir;
175   const bool have_test_data_dir =
176       base::PathService::Get(chrome::DIR_TEST_DATA, &extension_dir);
177   ASSERT_TRUE(have_test_data_dir);
178   extension_dir = extension_dir.AppendASCII("extensions")
179                       .AppendASCII("no_best_effort_tasks_test_extension");
180   extensions::TestExtensionRegistryObserver observer(
181       extensions::ExtensionRegistry::Get(browser()->profile()));
182   extensions::UnpackedInstaller::Create(
183       extensions::ExtensionSystem::Get(browser()->profile())
184           ->extension_service())
185       ->Load(extension_dir);
186   scoped_refptr<const extensions::Extension> extension =
187       observer.WaitForExtensionReady();
188   ASSERT_TRUE(extension);
189   ASSERT_EQ(kExtensionId, extension->id());
190
191   // Navigate to a test page, waiting until complete. Note that the hostname
192   // here must match the pattern found in the extension's manifest file, or it
193   // will not be able to send/receive messaging from the test web page (due to
194   // extension permissions).
195   ASSERT_TRUE(ui_test_utils::NavigateToURL(
196       browser(),
197       embedded_test_server()->GetURL("fake.chromium.org", "/empty.html")));
198
199   // Execute JavaScript in the test page, to send a ping message to the
200   // extension and await the reply. The chrome.runtime.sendMessage() operation
201   // can fail if the extension's background page hasn't finished running yet
202   // (i.e., there is no message listener yet). Thus, use a retry loop.
203   const std::string request_reply_javascript = base::StringPrintf(
204       "new Promise((resolve, reject) => {\n"
205       "  chrome.runtime.sendMessage(\n"
206       "      '%s',\n"
207       "      {ping: true},\n"
208       "      response => {\n"
209       "        if (response) {\n"
210       "          resolve(response);\n"
211       "        } else {\n"
212       "          reject(chrome.runtime.lastError.message);\n"
213       "        }\n"
214       "      });\n"
215       "})",
216       extension->id().c_str());
217   for (;;) {
218     const auto result =
219         content::EvalJs(browser()->tab_strip_model()->GetActiveWebContents(),
220                         request_reply_javascript);
221     if (result.error.empty()) {
222       LOG(INFO) << "Got a response from the extension.";
223       EXPECT_TRUE(result.value.GetDict().FindBool("pong").value_or(false));
224       break;
225     }
226     // An error indicates the extension's message listener isn't up yet. Wait a
227     // little before trying again.
228     LOG(INFO) << "Waiting for the extension's message listener...";
229     base::RunLoop run_loop;
230     base::SequencedTaskRunner::GetCurrentDefault()->PostDelayedTask(
231         FROM_HERE, run_loop.QuitClosure(), kSendMessageRetryPeriod);
232     run_loop.Run();
233   }
234 }
235 #endif  // BUILDFLAG(ENABLE_EXTENSIONS)
236
237 // Verify that Blob XMLHttpRequest finishes without running BEST_EFFORT tasks.
238 // Regression test for https://crbug.com/989868.
239 IN_PROC_BROWSER_TEST_F(NoBestEffortTasksTest, BlobXMLHttpRequest) {
240   ASSERT_TRUE(embedded_test_server()->Start());
241   ASSERT_TRUE(ui_test_utils::NavigateToURL(
242       browser(), embedded_test_server()->GetURL("/empty.html")));
243   const char kScript[] = R"(
244       new Promise(function (resolve, reject) {
245         const xhr = new XMLHttpRequest();
246         xhr.open("GET", "./empty.html?", true);
247         xhr.responseType = "blob";
248         xhr.onload = () => {
249           resolve('DONE');
250         };
251         xhr.send();
252       })
253   )";
254   EXPECT_EQ("DONE",
255             content::EvalJs(
256                 browser()->tab_strip_model()->GetActiveWebContents(), kScript));
257 }
258
259 // A test specialization for verifying quota storage related operations do not
260 // use BEST_EFFORT tasks.
261 class NoBestEffortTasksTestWithQuota : public NoBestEffortTasksTest {
262  protected:
263   bool UseProductionQuotaSettings() override {
264     // Return true to use the real quota subsystem.
265     return true;
266   }
267 };
268
269 // Verify that cache_storage finishes without running BEST_EFFORT tasks.
270 // Regression test for https://crbug.com/1006546.
271 IN_PROC_BROWSER_TEST_F(NoBestEffortTasksTestWithQuota, CacheStorage) {
272   ASSERT_TRUE(embedded_test_server()->Start());
273   ASSERT_TRUE(ui_test_utils::NavigateToURL(
274       browser(), embedded_test_server()->GetURL("/empty.html")));
275   const char kScript[] = R"(
276       (async function() {
277         const name = 'foo';
278         const url = '/';
279         const body = 'hello world';
280         let c = await caches.open(name);
281         await c.put(url, new Response(body));
282         let r = await c.match(url);
283         await r.text();
284         return 'DONE';
285       })();
286   )";
287   EXPECT_EQ("DONE",
288             content::EvalJs(
289                 browser()->tab_strip_model()->GetActiveWebContents(), kScript));
290 }
291
292 // Verify that quota estimate() finishes without running BEST_EFFORT tasks.
293 // Regression test for https://crbug.com/1006546.
294 IN_PROC_BROWSER_TEST_F(NoBestEffortTasksTestWithQuota, QuotaEstimate) {
295   ASSERT_TRUE(embedded_test_server()->Start());
296   ASSERT_TRUE(ui_test_utils::NavigateToURL(
297       browser(), embedded_test_server()->GetURL("/empty.html")));
298   const char kScript[] = R"(
299       (async function() {
300         await navigator.storage.estimate();
301         return 'DONE';
302       })();
303   )";
304   EXPECT_EQ("DONE",
305             content::EvalJs(
306                 browser()->tab_strip_model()->GetActiveWebContents(), kScript));
307 }