// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/**
 * @fileoverview Framework for running JavaScript tests of Polymer elements.
 */

/**
 * Test fixture for Polymer element testing.
 * @constructor
 * @extends testing.Test
 */
function PolymerTest() {}

PolymerTest.prototype = {
  __proto__: testing.Test.prototype,

  /**
   * Navigate to a WebUI to satisfy BrowserTest conditions. Override to load a
   * more useful WebUI.
   * @override
   */
  browsePreload: 'chrome://chrome-urls/',

  /**
   * The mocha adapter assumes all tests are async.
   * @override
   * @final
   */
  isAsync: true,

  /**
   * Old style a11y checks are obsolete. See ../a11y/accessibility_test.js for
   * the new suggested way.
   * @override
   */
  runAccessibilityChecks: false,

  /**
   * Files that need not be compiled.
   * @override
   */
  extraLibraries: [
    '//ui/webui/resources/js/cr.js',
    '//ui/webui/resources/js/promise_resolver.js',
    '//third_party/mocha/mocha.js',
    '//chrome/test/data/webui/mocha_adapter.js',
    '//third_party/polymer/v1_0/components-chromium/iron-test-helpers/' +
        'mock-interactions.js',
  ],

  /** @override */
  setUp: function() {
    testing.Test.prototype.setUp.call(this);

    // List of imported URLs for debugging purposes.
    PolymerTest.importUrls_ = [];
    PolymerTest.scriptUrls_ = [];

    // Importing a URL like "chrome://settings/foo" redirects to the base
    // ("chrome://settings") page, which due to how browsePreload works can
    // result in duplicate imports. Wrap document.registerElement so failures
    // caused by re-registering Polymer elements are caught; otherwise Chrome
    // simply throws "Script error" which is unhelpful.
    var originalRegisterElement = document.registerElement;
    document.registerElement = function() {
      try {
        return originalRegisterElement.apply(document, arguments);
      } catch (e) {
        var msg =
            'If the call to document.registerElement failed because a type ' +
            'is already registered, perhaps you have loaded a script twice. ' +
            'Incorrect resource URLs can redirect to base WebUI pages; make ' +
            'sure the following URLs are correct and unique:\n';
        for (var i = 0; i < PolymerTest.importUrls_.length; i++) {
          msg += '  ' + PolymerTest.importUrls_[i] + '\n';
        }
        for (var i = 0; i < PolymerTest.scriptUrls_.length; i++) {
          msg += '  ' + PolymerTest.scriptUrls_[i] + '\n';
        }
        console.error(msg);

        // Mocha will handle the error.
        throw e;
      }
    };
  },

  /** @override */
  tearDown: function() {
    // Note: We do this in tearDown() so that we have a chance to stamp all the
    // dom-if templates, add elements through interaction, etc.
    PolymerTest.testIronIcons(document.body);

    testing.Test.prototype.tearDown.call(this);
  }
};

/**
 * Tests that any iron-icon child of an HTML element has a corresponding
 * non-empty svg element.
 * @param {!HTMLElement} e The element to check the iron icons in.
 */
PolymerTest.testIronIcons = function(e) {
  e.querySelectorAll('* /deep/ iron-icon').forEach(function(icon) {
    // Early return if the src is set instead of the icon, since the tests
    // below will not work correctly in this case.
    if (icon.src && !icon.icon) {
      return;
    }

    // If the icon isn't set (or is set to ''), then don't test this. Having no
    // set icon is valid for cases when we don't want to display anything.
    if (!icon.icon) {
      var rect = icon.getBoundingClientRect();
      expectFalse(
          rect.width * rect.height > 0,
          'iron-icon with undefined "icon" is visible in the DOM.');
      return;
    }
    var svg = icon.$$('svg');
    expectTrue(
        !!svg && svg.innerHTML != '',
        'icon "' + icon.icon + '" is not present');
  });
};

/**
 * Imports the HTML file.
 * @param {string} src The URL to load.
 * @return {!Promise} A promise that is resolved/rejected on success/failure.
 */
PolymerTest.importHtml = function(src) {
  PolymerTest.importUrls_.push(src);
  var link = document.createElement('link');
  link.rel = 'import';
  var promise = new Promise(function(resolve, reject) {
    link.onload = resolve;
    link.onerror = reject;
  });
  link.href = src;
  document.head.appendChild(link);
  return promise;
};

/**
 * Loads the script file.
 * @param {string} src The URL to load.
 * @return {!Promise} A promise that is resolved/rejected on success/failure.
 */
PolymerTest.loadScript = function(src) {
  PolymerTest.scriptUrls_.push(src);
  var script = document.createElement('script');
  var promise = new Promise(function(resolve, reject) {
    script.onload = resolve;
    script.onerror = reject;
  });
  script.src = src;
  document.head.appendChild(script);
  return promise;
};

/**
 * Removes all content from the body. In a vulcanized build, this retains the
 * inlined tags so stylesheets and dom-modules are not discarded.
 */
PolymerTest.clearBody = function() {
  // Save the div where vulcanize inlines content before clearing the page.
  var vulcanizeDiv =
      document.querySelector('body > div[hidden][by-polymer-bundler]');
  document.body.innerHTML = '';
  if (vulcanizeDiv) {
    document.body.appendChild(vulcanizeDiv);
  }
};

/*
 * Waits for queued up tasks to finish before proceeding. Inspired by:
 * https://github.com/Polymer/web-component-tester/blob/master/browser/environment/helpers.js#L97
 */
PolymerTest.flushTasks = function() {
  Polymer.dom.flush();
  // Promises have microtask timing, so we use setTimeout to explicity force a
  // new task.
  return new Promise(function(resolve, reject) {
    window.setTimeout(resolve, 0);
  });
};

/**
 * @param {!HTMLElement} element
 * @return {!Promise} Promise that resolves when an afterNextRender()
 *     callback on |element| is run.
 */
PolymerTest.afterNextRender = function(element) {
  return new Promise(resolve => {
    Polymer.RenderStatus.afterNextRender(element, resolve);
  });
};
