1 // Copyright 2013 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 <string>
6
7 #include "base/command_line.h"
8 #include "base/file_util.h"
9 #include "base/files/file_path.h"
10 #include "chrome/browser/ui/browser.h"
11 #include "chrome/browser/ui/tabs/tab_strip_model.h"
12 #include "chrome/common/chrome_switches.h"
13 #include "chrome/test/base/in_process_browser_test.h"
14 #include "chrome/test/base/ui_test_utils.h"
15 #include "content/public/browser/navigation_details.h"
16 #include "content/public/test/browser_test_utils.h"
17 #include "grit/browser_resources.h"
18 #include "ui/base/resource/resource_bundle.h"
19 #include "url/gurl.h"
20
21 namespace {
22
CreateResource(const std::string & content)23 GURL CreateResource(const std::string& content) {
24 base::FilePath path;
25 EXPECT_TRUE(base::CreateTemporaryFile(&path));
26 EXPECT_TRUE(base::WriteFile(path, content.c_str(), content.size()));
27 return GURL("file:///" + path.AsUTF8Unsafe());
28 }
29
30 // Test the CrOS login screen resource loading mechanism.
31 class ResourceLoaderBrowserTest : public InProcessBrowserTest {
32 public:
ResourceLoaderBrowserTest()33 ResourceLoaderBrowserTest() {}
34
35 protected:
SetUpCommandLine(CommandLine * command_line)36 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
37 // Needed to load file:// URLs in XHRs.
38 command_line->AppendSwitch(switches::kDisableWebSecurity);
39 }
40
SetUpOnMainThread()41 virtual void SetUpOnMainThread() OVERRIDE {
42 // Create the root page containing resource_loader.js.
43 std::string root_page =
44 "<html>"
45 "<head>"
46 "<script>"
47 " cr = { ui: { login: {} } };"
48 " cr.define = function (path, builder) {"
49 " cr.ui.login.ResourceLoader = builder();"
50 " };"
51 " $ = document.getElementById.bind(document);"
52 "</script>"
53 "<script>";
54 ResourceBundle::GetSharedInstance().GetRawDataResource(
55 IDR_OOBE_RESOURCE_LOADER_JS).AppendToString(&root_page);
56 root_page +=
57 "</script>"
58 "</head>"
59 "<body>"
60 "<div id=\"root\"></div>"
61 "</body>"
62 "</html>";
63 ui_test_utils::NavigateToURL(browser(), CreateResource(root_page));
64 JSExpect("!!document.querySelector('#root')");
65
66 // Define global alias for convenience.
67 JSEval("ResourceLoader = cr.ui.login.ResourceLoader;");
68 }
69
JSEval(const std::string & script)70 void JSEval(const std::string& script) {
71 EXPECT_TRUE(content::ExecuteScript(
72 browser()->tab_strip_model()->GetActiveWebContents(), script));
73 }
74
JSExpect(const std::string & expression)75 void JSExpect(const std::string& expression) {
76 bool result;
77 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
78 browser()->tab_strip_model()->GetActiveWebContents(),
79 "window.domAutomationController.send(!!(" + expression + "));",
80 &result));
81 EXPECT_TRUE(result) << expression;
82 }
83
JSExpectAsync(const std::string & function)84 void JSExpectAsync(const std::string& function) {
85 bool result;
86 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
87 browser()->tab_strip_model()->GetActiveWebContents(),
88 "(" + function + ")(function() {"
89 " window.domAutomationController.send(true);"
90 "});",
91 &result));
92 EXPECT_TRUE(result);
93 }
94
95 private:
96 DISALLOW_COPY_AND_ASSIGN(ResourceLoaderBrowserTest);
97 };
98
IN_PROC_BROWSER_TEST_F(ResourceLoaderBrowserTest,RegisterAssetsTest)99 IN_PROC_BROWSER_TEST_F(ResourceLoaderBrowserTest, RegisterAssetsTest) {
100 JSExpect("!ResourceLoader.hasDeferredAssets('foo')");
101 JSEval("ResourceLoader.registerAssets({ id: 'foo' });");
102 JSExpect("ResourceLoader.hasDeferredAssets('foo')");
103 }
104
IN_PROC_BROWSER_TEST_F(ResourceLoaderBrowserTest,LoadAssetsTest)105 IN_PROC_BROWSER_TEST_F(ResourceLoaderBrowserTest, LoadAssetsTest) {
106 // Create a flag to set when the JavaScript is loaded.
107 JSEval("stuff = {}");
108
109 // Create the assets.
110 std::string html_url = CreateResource("<h1 id=\"bar\">foo</h1>").spec();
111 std::string css_url = CreateResource("h1 { color: red; }").spec();
112 std::string js_url = CreateResource("stuff.loaded = true;").spec();
113
114 // Register the asset bundle.
115 JSEval("ResourceLoader.registerAssets({"
116 " id: 'test-bundle',"
117 " html: [ { url: '" + html_url + "', targetID: 'root' } ]," +
118 " css: [ '" + css_url + "' ]," +
119 " js: [ '" + js_url + "' ]," +
120 "});");
121 JSExpect("!ResourceLoader.alreadyLoadedAssets('test-bundle')");
122
123 // Load the assets and make sure everything is properly added to the page.
124 JSExpectAsync("ResourceLoader.loadAssets.bind(null, 'test-bundle')");
125 JSExpect("ResourceLoader.alreadyLoadedAssets('test-bundle')");
126
127 // Check that the HTML was inserted into the root div.
128 JSExpect("!!document.querySelector('div#root h1#bar')");
129
130 // Check that the JS was loaded and evaluated.
131 JSExpect("stuff.loaded");
132
133 // Check that the styles were loaded.
134 JSExpect("!!document.head.querySelector('link').innerHTML.indexOf('red')");
135 }
136
137 } // namespace
138