17d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
27d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
37d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// found in the LICENSE file.
47d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
57d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include <string>
67d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
77d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/command_line.h"
87d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/files/file_path.h"
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h"
127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/test/base/in_process_browser_test.h"
147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/test/base/ui_test_utils.h"
157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/public/browser/navigation_details.h"
167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/public/test/browser_test_utils.h"
175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "grit/login_resources.h"
187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h"
207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace {
227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)GURL CreateResource(const std::string& content) {
247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::FilePath path;
25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(base::CreateTemporaryFile(&path));
26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_TRUE(base::WriteFile(path, content.c_str(), content.size()));
277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return GURL("file:///" + path.AsUTF8Unsafe());
287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Test the CrOS login screen resource loading mechanism.
317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class ResourceLoaderBrowserTest : public InProcessBrowserTest {
327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) public:
337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ResourceLoaderBrowserTest() {}
347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) protected:
367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // Needed to load file:// URLs in XHRs.
387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    command_line->AppendSwitch(switches::kDisableWebSecurity);
397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual void SetUpOnMainThread() OVERRIDE {
427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // Create the root page containing resource_loader.js.
437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    std::string root_page =
447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        "<html>"
457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        "<head>"
467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        "<script>"
477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        "  cr = { ui: { login: {} } };"
487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        "  cr.define = function (path, builder) {"
497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        "    cr.ui.login.ResourceLoader = builder();"
507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        "  };"
517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        "  $ = document.getElementById.bind(document);"
527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        "</script>"
537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        "<script>";
547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    ResourceBundle::GetSharedInstance().GetRawDataResource(
557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        IDR_OOBE_RESOURCE_LOADER_JS).AppendToString(&root_page);
567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    root_page +=
577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        "</script>"
587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        "</head>"
597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        "<body>"
607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        "<div id=\"root\"></div>"
617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        "</body>"
627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        "</html>";
637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    ui_test_utils::NavigateToURL(browser(), CreateResource(root_page));
647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    JSExpect("!!document.querySelector('#root')");
657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // Define global alias for convenience.
677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    JSEval("ResourceLoader = cr.ui.login.ResourceLoader;");
687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void JSEval(const std::string& script) {
717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_TRUE(content::ExecuteScript(
727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        browser()->tab_strip_model()->GetActiveWebContents(), script));
737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void JSExpect(const std::string& expression) {
767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    bool result;
777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        browser()->tab_strip_model()->GetActiveWebContents(),
797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        "window.domAutomationController.send(!!(" + expression + "));",
807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        &result));
817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_TRUE(result) << expression;
827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void JSExpectAsync(const std::string& function) {
857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    bool result;
867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        browser()->tab_strip_model()->GetActiveWebContents(),
887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        "(" + function + ")(function() {"
897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        "  window.domAutomationController.send(true);"
907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        "});",
917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        &result));
927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_TRUE(result);
937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) private:
967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ResourceLoaderBrowserTest);
977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)};
987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(ResourceLoaderBrowserTest, RegisterAssetsTest) {
1007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  JSExpect("!ResourceLoader.hasDeferredAssets('foo')");
1017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  JSEval("ResourceLoader.registerAssets({ id: 'foo' });");
1027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  JSExpect("ResourceLoader.hasDeferredAssets('foo')");
1037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(ResourceLoaderBrowserTest, LoadAssetsTest) {
1067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Create a flag to set when the JavaScript is loaded.
1077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  JSEval("stuff = {}");
1087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Create the assets.
1107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  std::string html_url = CreateResource("<h1 id=\"bar\">foo</h1>").spec();
1117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  std::string css_url = CreateResource("h1 { color: red; }").spec();
1127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  std::string js_url = CreateResource("stuff.loaded = true;").spec();
1137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Register the asset bundle.
1157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  JSEval("ResourceLoader.registerAssets({"
1167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)         "  id: 'test-bundle',"
1177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)         "  html: [ { url: '" + html_url + "', targetID: 'root' } ]," +
1187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)         "  css: [ '" + css_url + "' ]," +
1197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)         "  js: [ '" + js_url + "' ]," +
1207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)         "});");
1217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  JSExpect("!ResourceLoader.alreadyLoadedAssets('test-bundle')");
1227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Load the assets and make sure everything is properly added to the page.
1247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  JSExpectAsync("ResourceLoader.loadAssets.bind(null, 'test-bundle')");
1257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  JSExpect("ResourceLoader.alreadyLoadedAssets('test-bundle')");
1267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Check that the HTML was inserted into the root div.
1287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  JSExpect("!!document.querySelector('div#root h1#bar')");
1297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Check that the JS was loaded and evaluated.
1317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  JSExpect("stuff.loaded");
1327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Check that the styles were loaded.
1347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  JSExpect("!!document.head.querySelector('link').innerHTML.indexOf('red')");
1357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}  // namespace
138