Home | History | Annotate | Download | only in login
      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/files/file_path.h"
      9 #include "base/files/file_util.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/login_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(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:
     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