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 23 GURL CreateResource(const std::string& content) { 24 base::FilePath path; 25 EXPECT_TRUE(file_util::CreateTemporaryFile(&path)); 26 EXPECT_TRUE(file_util::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: 33 ResourceLoaderBrowserTest() {} 34 35 protected: 36 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 37 // Needed to load file:// URLs in XHRs. 38 command_line->AppendSwitch(switches::kDisableWebSecurity); 39 } 40 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 70 void JSEval(const std::string& script) { 71 EXPECT_TRUE(content::ExecuteScript( 72 browser()->tab_strip_model()->GetActiveWebContents(), script)); 73 } 74 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 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 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 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