// Copyright 2016 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 using private properties isn't a Closure violation in tests.
 * @suppress {accessControls}
 */

/* eslint-disable no-console */

/**
 * @return {boolean}
 */
export function _isDebugTest() {
  return !self.testRunner || !!Root.Runtime.queryParam('debugFrontend');
}

/**
 * @return {boolean}
 */
export function _isStartupTest() {
  return Root.Runtime.queryParam('test').includes('/startup/');
}

/**
 * @param {string} messageType
 */
export function _consoleOutputHook(messageType) {
  addResult(messageType + ': ' + Array.prototype.slice.call(arguments, 1));
}

/**
 * This monkey patches console functions in DevTools context so the console
 * messages are shown in the right places, instead of having all of the console
 * messages printed at the top of the test expectation file (default behavior).
 */
export function _printDevToolsConsole() {
  if (_isDebugTest()) {
    return;
  }
  console.log = _consoleOutputHook.bind(null, 'log');
  console.error = _consoleOutputHook.bind(null, 'error');
  console.info = _consoleOutputHook.bind(null, 'info');
}

/**
 * @param {string|!Event} message
 * @param {string} source
 * @param {number} lineno
 * @param {number} colno
 * @param {!Error} error
 */
function completeTestOnError(message, source, lineno, colno, error) {
  addResult('TEST ENDED IN ERROR: ' + error.stack);
  completeTest();
}

self['onerror'] = completeTestOnError;
_printDevToolsConsole();

// TODO(crbug.com/1032477): Re-enable once test timeouts are handled in Chromium
// setTimeout(() => {
//   addResult('TEST TIMED OUT!');
//   completeTest();
// }, 6000);

/** @type {!Array<string>} */
let _results = [];

let _innerAddResult = text => {
  _results.push(String(text));
};

/**
 * @param {*} text
 */
export function addResult(text) {
  _innerAddResult(text);
}

let completed = false;

let _innerCompleteTest = () => {
  if (completed) {
    return;
  }
  completed = true;
  flushResults();
  self.testRunner.notifyDone();
};

export function completeTest() {
  _innerCompleteTest();
}

self.TestRunner = {
  _startupTestSetupFinished: () => {}
};

/**
 * Only tests in web_tests/http/tests/devtools/startup/ need to call
 * this method because these tests need certain activities to be exercised
 * in the inspected page prior to the DevTools session.
 * @param {string} path
 * @return {!Promise<undefined>}
 */
export function setupStartupTest(path) {
  const absoluteURL = url(path);
  const promise = new Promise(f => TestRunner._startupTestSetupFinished = () => {
    TestRunner._initializeTargetForStartupTest();
    delete TestRunner._startupTestSetupFinished;
    f();
  });
  self.testRunner.navigateSecondaryWindow(absoluteURL);
  return promise;
}

/**
 * @suppressGlobalPropertiesCheck
 */
export function flushResults() {
  Array.prototype.forEach.call(document.documentElement.childNodes, x => x.remove());
  const outputElement = document.createElement('div');
  // Support for svg - add to document, not body, check for style.
  if (outputElement.style) {
    outputElement.style.whiteSpace = 'pre';
    outputElement.style.height = '10px';
    outputElement.style.overflow = 'hidden';
  }
  document.documentElement.appendChild(outputElement);
  for (let i = 0; i < _results.length; i++) {
    outputElement.appendChild(document.createTextNode(_results[i]));
    outputElement.appendChild(document.createElement('br'));
  }
  _results = [];
}

export function _executeTestScript() {
  const testScriptURL = /** @type {string} */ (Root.Runtime.queryParam('test'));
  fetch(testScriptURL)
      .then(data => data.text())
      .then(testScript => {
        if (_isDebugTest()) {
          _innerAddResult = console.log;
          _innerCompleteTest = () => console.log('Test completed');

          // Auto-start unit tests
          if (!self.testRunner) {
            eval(`(function test(){${testScript}})()\n//# sourceURL=${testScriptURL}`);
          } else {
            self.eval(`function test(){${testScript}}\n//# sourceURL=${testScriptURL}`);
          }
          return;
        }

        // Convert the test script into an expression (if needed)
        testScript = testScript.trimRight();
        if (testScript.endsWith(';')) {
          testScript = testScript.slice(0, testScript.length - 1);
        }

        (async function() {
          try {
            await eval(testScript + `\n//# sourceURL=${testScriptURL}`);
          } catch (err) {
            addResult('TEST ENDED EARLY DUE TO UNCAUGHT ERROR:');
            addResult(err && err.stack || err);
            addResult('=== DO NOT COMMIT THIS INTO -expected.txt ===');
            completeTest();
          }
        })();
      })
      .catch(error => {
        addResult(`Unable to execute test script because of error: ${error}`);
        completeTest();
      });
}

/**
 * @param {!Array<string>} textArray
 */
export function addResults(textArray) {
  if (!textArray) {
    return;
  }
  for (let i = 0, size = textArray.length; i < size; ++i) {
    addResult(textArray[i]);
  }
}

/**
 * @param {!Array<function()>} tests
 */
export function runTests(tests) {
  nextTest();

  function nextTest() {
    const test = tests.shift();
    if (!test) {
      completeTest();
      return;
    }
    addResult('\ntest: ' + test.name);
    let testPromise = test();
    if (!(testPromise instanceof Promise)) {
      testPromise = Promise.resolve();
    }
    testPromise.then(nextTest);
  }
}

/**
 * @param {!Object} receiver
 * @param {string} methodName
 * @param {!Function} override
 * @param {boolean=} opt_sticky
 */
export function addSniffer(receiver, methodName, override, opt_sticky) {
  override = safeWrap(override);

  const original = receiver[methodName];
  if (typeof original !== 'function') {
    throw new Error('Cannot find method to override: ' + methodName);
  }

  receiver[methodName] = function(var_args) {
    let result;
    try {
      result = original.apply(this, arguments);
    } finally {
      if (!opt_sticky) {
        receiver[methodName] = original;
      }
    }
    // In case of exception the override won't be called.
    try {
      Array.prototype.push.call(arguments, result);
      override.apply(this, arguments);
    } catch (e) {
      throw new Error('Exception in overriden method \'' + methodName + '\': ' + e);
    }
    return result;
  };
}

/**
 * @param {!Object} receiver
 * @param {string} methodName
 * @return {!Promise<*>}
 */
export function addSnifferPromise(receiver, methodName) {
  return new Promise(function(resolve, reject) {
    const original = receiver[methodName];
    if (typeof original !== 'function') {
      reject('Cannot find method to override: ' + methodName);
      return;
    }

    receiver[methodName] = function(var_args) {
      let result;
      try {
        result = original.apply(this, arguments);
      } finally {
        receiver[methodName] = original;
      }
      // In case of exception the override won't be called.
      try {
        Array.prototype.push.call(arguments, result);
        resolve.apply(this, arguments);
      } catch (e) {
        reject('Exception in overridden method \'' + methodName + '\': ' + e);
        completeTest();
      }
      return result;
    };
  });
}

/** @type {function():void} */
let _resolveOnFinishInits;

/**
 * @param {string} module
 * @return {!Promise<undefined>}
 */
export async function loadModule(module) {
  const promise = new Promise(resolve => _resolveOnFinishInits = resolve);
  await self.runtime.loadModulePromise(module);
  if (!_pendingInits) {
    return;
  }
  return promise;
}

/**
 * @param {string} panel
 * @return {!Promise.<?UI.Panel>}
 */
export function showPanel(panel) {
  return UI.viewManager.showView(panel);
}

/**
 * @param {string} key
 * @param {boolean=} ctrlKey
 * @param {boolean=} altKey
 * @param {boolean=} shiftKey
 * @param {boolean=} metaKey
 * @return {!KeyboardEvent}
 */
export function createKeyEvent(key, ctrlKey, altKey, shiftKey, metaKey) {
  return new KeyboardEvent('keydown', {
    key: key,
    bubbles: true,
    cancelable: true,
    ctrlKey: !!ctrlKey,
    altKey: !!altKey,
    shiftKey: !!shiftKey,
    metaKey: !!metaKey
  });
}

/**
 * Wraps a test function with an exception filter. Does not work
 * correctly for async functions; use safeAsyncWrap instead.
 * @param {!Function|undefined} func
 * @param {!Function=} onexception
 * @return {!Function}
 */
export function safeWrap(func, onexception) {
  /**
   * @this {*}
   */
  function result() {
    if (!func) {
      return;
    }
    const wrapThis = this;
    try {
      return func.apply(wrapThis, arguments);
    } catch (e) {
      addResult('Exception while running: ' + func + '\n' + (e.stack || e));
      if (onexception) {
        safeWrap(onexception)();
      } else {
        completeTest();
      }
    }
  }
  return result;
}

/**
 * Wraps a test function that returns a Promise with an exception
 * filter. Does not work correctly for functions which don't return
 * a Promise; use safeWrap instead.
 * @param {function(...):Promise<*>} func
 * @return {function(...):Promise<*>}
 */
export function safeAsyncWrap(func) {
  /**
   * @this {*}
   */
  async function result() {
    if (!func) {
      return;
    }
    const wrapThis = this;
    try {
      return await func.apply(wrapThis, arguments);
    } catch (e) {
      addResult('Exception while running: ' + func + '\n' + (e.stack || e));
      completeTest();
    }
  }
  return result;
}

/**
 * @param {!Node} node
 * @return {string}
 */
export function textContentWithLineBreaks(node) {
  function padding(currentNode) {
    let result = 0;
    while (currentNode && currentNode !== node) {
      if (currentNode.nodeName === 'OL' &&
          !(currentNode.classList && currentNode.classList.contains('object-properties-section'))) {
        ++result;
      }
      currentNode = currentNode.parentNode;
    }
    return Array(result * 4 + 1).join(' ');
  }

  let buffer = '';
  let currentNode = node;
  let ignoreFirst = false;
  while (currentNode.traverseNextNode(node)) {
    currentNode = currentNode.traverseNextNode(node);
    if (currentNode.nodeType === Node.TEXT_NODE) {
      buffer += currentNode.nodeValue;
    } else if (currentNode.nodeName === 'LI' || currentNode.nodeName === 'TR') {
      if (!ignoreFirst) {
        buffer += '\n' + padding(currentNode);
      } else {
        ignoreFirst = false;
      }
    } else if (currentNode.nodeName === 'STYLE') {
      currentNode = currentNode.traverseNextNode(node);
      continue;
    } else if (currentNode.classList && currentNode.classList.contains('object-properties-section')) {
      ignoreFirst = true;
    }
  }
  return buffer;
}

/**
 * @param {!Node} node
 * @return {string}
 */
export function textContentWithoutStyles(node) {
  let buffer = '';
  let currentNode = node;
  while (currentNode.traverseNextNode(node)) {
    currentNode = currentNode.traverseNextNode(node);
    if (currentNode.nodeType === Node.TEXT_NODE) {
      buffer += currentNode.nodeValue;
    } else if (currentNode.nodeName === 'STYLE') {
      currentNode = currentNode.traverseNextNode(node);
    }
  }
  return buffer;
}

/**
 * @param {!SDK.Target} target
 */
export function _setupTestHelpers(target) {
  TestRunner.BrowserAgent = target.browserAgent();
  TestRunner.CSSAgent = target.cssAgent();
  TestRunner.DeviceOrientationAgent = target.deviceOrientationAgent();
  TestRunner.DOMAgent = target.domAgent();
  TestRunner.DOMDebuggerAgent = target.domdebuggerAgent();
  TestRunner.DebuggerAgent = target.debuggerAgent();
  TestRunner.EmulationAgent = target.emulationAgent();
  TestRunner.HeapProfilerAgent = target.heapProfilerAgent();
  TestRunner.InputAgent = target.inputAgent();
  TestRunner.InspectorAgent = target.inspectorAgent();
  TestRunner.NetworkAgent = target.networkAgent();
  TestRunner.OverlayAgent = target.overlayAgent();
  TestRunner.PageAgent = target.pageAgent();
  TestRunner.ProfilerAgent = target.profilerAgent();
  TestRunner.RuntimeAgent = target.runtimeAgent();
  TestRunner.TargetAgent = target.targetAgent();

  TestRunner.networkManager = target.model(SDK.NetworkManager);
  TestRunner.securityOriginManager = target.model(SDK.SecurityOriginManager);
  TestRunner.resourceTreeModel = target.model(SDK.ResourceTreeModel);
  TestRunner.debuggerModel = target.model(SDK.DebuggerModel);
  TestRunner.runtimeModel = target.model(SDK.RuntimeModel);
  TestRunner.domModel = target.model(SDK.DOMModel);
  TestRunner.domDebuggerModel = target.model(SDK.DOMDebuggerModel);
  TestRunner.cssModel = target.model(SDK.CSSModel);
  TestRunner.cpuProfilerModel = target.model(SDK.CPUProfilerModel);
  TestRunner.overlayModel = target.model(SDK.OverlayModel);
  TestRunner.serviceWorkerManager = target.model(SDK.ServiceWorkerManager);
  TestRunner.tracingManager = target.model(SDK.TracingManager);
  TestRunner.mainTarget = target;
}

/**
 * @param {string} code
 * @return {!Promise<*>}
 */
export async function evaluateInPageRemoteObject(code) {
  const response = await _evaluateInPage(code);
  return TestRunner.runtimeModel.createRemoteObject(response.result);
}

/**
 * @param {string} code
 * @param {function(*, !Protocol.Runtime.ExceptionDetails=):void} callback
 */
export async function evaluateInPage(code, callback) {
  const response = await _evaluateInPage(code);
  safeWrap(callback)(response.result.value, response.exceptionDetails);
}

/** @type {number} */
let _evaluateInPageCounter = 0;

/**
 * @param {string} code
 * @return {!Promise<undefined|{response: (!SDK.RemoteObject|undefined),
 *   exceptionDetails: (!Protocol.Runtime.ExceptionDetails|undefined)}>}
 */
export async function _evaluateInPage(code) {
  const lines = new Error().stack.split('at ');

  // Handles cases where the function is safe wrapped
  const testScriptURL = /** @type {string} */ (Root.Runtime.queryParam('test'));
  const functionLine = lines.reduce((acc, line) => line.includes(testScriptURL) ? line : acc, lines[lines.length - 2]);

  const components = functionLine.trim().split('/');
  const source = components[components.length - 1].slice(0, -1).split(':');
  const fileName = source[0];
  const sourceURL = `test://evaluations/${_evaluateInPageCounter++}/` + fileName;
  const lineOffset = parseInt(source[1], 10);
  code = '\n'.repeat(lineOffset - 1) + code;
  if (code.indexOf('sourceURL=') === -1) {
    code += `//# sourceURL=${sourceURL}`;
  }
  const response = await TestRunner.RuntimeAgent.invoke_evaluate({expression: code, objectGroup: 'console'});
  const error = response[Protocol.Error];
  if (error) {
    addResult('Error: ' + error);
    completeTest();
    return;
  }
  return response;
}

/**
 * Doesn't append sourceURL to snippets evaluated in inspected page
 * to avoid churning test expectations
 * @param {string} code
 * @param {boolean=} userGesture
 * @return {!Promise<*>}
 */
export async function evaluateInPageAnonymously(code, userGesture) {
  const response =
      await TestRunner.RuntimeAgent.invoke_evaluate({expression: code, objectGroup: 'console', userGesture});
  if (!response[Protocol.Error]) {
    return response.result.value;
  }
  addResult(
      'Error: ' +
      (response.exceptionDetails && response.exceptionDetails.text || 'exception from evaluateInPageAnonymously.'));
  completeTest();
}

/**
 * @param {string} code
 * @return {!Promise<*>}
 */
export function evaluateInPagePromise(code) {
  return new Promise(success => evaluateInPage(code, success));
}

/**
 * @param {string} code
 * @return {!Promise<*>}
 */
export async function evaluateInPageAsync(code) {
  const response = await TestRunner.RuntimeAgent.invoke_evaluate(
      {expression: code, objectGroup: 'console', includeCommandLineAPI: false, awaitPromise: true});

  const error = response[Protocol.Error];
  if (!error && !response.exceptionDetails) {
    return response.result.value;
  }
  addResult(
      'Error: ' +
      (error || response.exceptionDetails && response.exceptionDetails.text || 'exception while evaluation in page.'));
  completeTest();
}

/**
 * @param {string} name
 * @param {!Array<*>} args
 * @return {!Promise<*>}
 */
export function callFunctionInPageAsync(name, args) {
  args = args || [];
  return evaluateInPageAsync(name + '(' + args.map(a => JSON.stringify(a)).join(',') + ')');
}

/**
 * @param {string} code
 * @param {boolean=} userGesture
 */
export function evaluateInPageWithTimeout(code, userGesture) {
  // FIXME: we need a better way of waiting for chromium events to happen
  evaluateInPageAnonymously('setTimeout(unescape(\'' + escape(code) + '\'), 1)', userGesture);
}

/**
 * @param {function():*} func
 * @param {function(*):void} callback
 */
export function evaluateFunctionInOverlay(func, callback) {
  const expression = 'internals.evaluateInInspectorOverlay("(" + ' + func + ' + ")()")';
  const mainContext = TestRunner.runtimeModel.executionContexts()[0];
  mainContext
      .evaluate(
          {
            expression: expression,
            objectGroup: '',
            includeCommandLineAPI: false,
            silent: false,
            returnByValue: true,
            generatePreview: false
          },
          /* userGesture */ false, /* awaitPromise*/ false)
      .then(result => void callback(result.object.value));
}

/**
 * @param {boolean} passCondition
 * @param {string} failureText
 */
export function check(passCondition, failureText) {
  if (!passCondition) {
    addResult('FAIL: ' + failureText);
  }
}

/**
 * @param {!Function} callback
 */
export function deprecatedRunAfterPendingDispatches(callback) {
  Protocol.test.deprecatedRunAfterPendingDispatches(callback);
}

/**
 * This ensures a base tag is set so all DOM references
 * are relative to the test file and not the inspected page
 * (i.e. http/tests/devtools/resources/inspected-page.html).
 * @param {string} html
 * @return {!Promise<*>}
 */
export function loadHTML(html) {
  if (!html.includes('<base')) {
    // <!DOCTYPE...> tag needs to be first
    const doctypeRegex = /(<!DOCTYPE.*?>)/i;
    const baseTag = `<base href="${url()}">`;
    if (html.match(doctypeRegex)) {
      html = html.replace(doctypeRegex, '$1' + baseTag);
    } else {
      html = baseTag + html;
    }
  }
  html = html.replace(/'/g, '\\\'').replace(/\n/g, '\\n');
  return evaluateInPageAnonymously(`document.write(\`${html}\`);document.close();`);
}

/**
 * @param {string} path
 * @return {!Promise<*>}
 */
export function addScriptTag(path) {
  return evaluateInPageAsync(`
    (function(){
      let script = document.createElement('script');
      script.src = '${path}';
      document.head.append(script);
      return new Promise(f => script.onload = f);
    })();
  `);
}

/**
 * @param {string} path
 * @return {!Promise<*>}
 */
export function addStylesheetTag(path) {
  return evaluateInPageAsync(`
    (function(){
      const link = document.createElement('link');
      link.rel = 'stylesheet';
      link.href = '${path}';
      link.onload = onload;
      document.head.append(link);
      let resolve;
      const promise = new Promise(r => resolve = r);
      function onload() {
        // TODO(chenwilliam): It shouldn't be necessary to force
        // style recalc here but some tests rely on it.
        window.getComputedStyle(document.body).color;
        resolve();
      }
      return promise;
    })();
  `);
}

/**
 * @param {string} path
 * @return {!Promise<*>}
 */
export function addHTMLImport(path) {
  return evaluateInPageAsync(`
    (function(){
      const link = document.createElement('link');
      link.rel = 'import';
      link.href = '${path}';
      const promise = new Promise(r => link.onload = r);
      document.body.append(link);
      return promise;
    })();
  `);
}

/**
 * NOTE you should manually ensure the path is correct. There
 * is no error event triggered if it is incorrect, and this is
 * in line with the standard (crbug 365457).
 * @param {string} path
 * @param {!Object|undefined} options
 * @return {!Promise<*>}
 */
export function addIframe(path, options = {}) {
  options.id = options.id || '';
  options.name = options.name || '';
  return evaluateInPageAsync(`
    (function(){
      const iframe = document.createElement('iframe');
      iframe.src = '${path}';
      iframe.id = '${options.id}';
      iframe.name = '${options.name}';
      document.body.appendChild(iframe);
      return new Promise(f => iframe.onload = f);
    })();
  `);
}

/** @type {number} */
let _pendingInits = 0;

/**
 * The old test framework executed certain snippets in the inspected page
 * context as part of loading a test helper file.
 *
 * This is deprecated because:
 * 1) it makes the testing API less intuitive (need to read the various *TestRunner.js
 * files to know which helper functions are available in the inspected page).
 * 2) it complicates the test framework's module loading process.
 *
 * In most cases, this is used to set up inspected page functions (e.g. makeSimpleXHR)
 * which should become a *TestRunner method (e.g. NetworkTestRunner.makeSimpleXHR)
 * that calls evaluateInPageAnonymously(...).
 * @param {string} code
 */
export async function deprecatedInitAsync(code) {
  _pendingInits++;
  await TestRunner.RuntimeAgent.invoke_evaluate({expression: code, objectGroup: 'console'});
  _pendingInits--;
  if (!_pendingInits) {
    _resolveOnFinishInits();
  }
}

/**
 * @param {string} title
 */
export function markStep(title) {
  addResult('\nRunning: ' + title);
}

export function startDumpingProtocolMessages() {
  Protocol.test.dumpProtocol = self.testRunner.logToStderr.bind(self.testRunner);
}

/**
 * @param {string} url
 * @param {string} content
 * @param {!SDK.ResourceTreeFrame} frame
 */
export function addScriptForFrame(url, content, frame) {
  content += '\n//# sourceURL=' + url;
  const executionContext = TestRunner.runtimeModel.executionContexts().find(context => context.frameId === frame.id);
  TestRunner.RuntimeAgent.evaluate(content, 'console', false, false, executionContext.id);
}

export const formatters = {


  /**
 * @param {*} value
 * @return {string}
 */
  formatAsTypeName(value) {
    return '<' + typeof value + '>';
  },

  /**
 * @param {*} value
 * @return {string}
 */
  formatAsTypeNameOrNull(value) {
    if (value === null) {
      return 'null';
    }
    return formatters.formatAsTypeName(value);
  },

  /**
 * @param {*} value
 * @return {string|!Date}
 */
  formatAsRecentTime(value) {
    if (typeof value !== 'object' || !(value instanceof Date)) {
      return formatters.formatAsTypeName(value);
    }
    const delta = Date.now() - value;
    return 0 <= delta && delta < 30 * 60 * 1000 ? '<plausible>' : value;
  },

  /**
 * @param {string} value
 * @return {string}
 */
  formatAsURL(value) {
    if (!value) {
      return value;
    }
    const lastIndex = value.lastIndexOf('devtools/');
    if (lastIndex < 0) {
      return value;
    }
    return '.../' + value.substr(lastIndex);
  },

  /**
 * @param {string} value
 * @return {string}
 */
  formatAsDescription(value) {
    if (!value) {
      return value;
    }
    return '"' + value.replace(/^function [gs]et /, 'function ') + '"';
  },
};

/**
 * @param {!Object} object
 * @param {!TestRunner.CustomFormatters=} customFormatters
 * @param {string=} prefix
 * @param {string=} firstLinePrefix
 */
export function addObject(object, customFormatters, prefix, firstLinePrefix) {
  prefix = prefix || '';
  firstLinePrefix = firstLinePrefix || prefix;
  addResult(firstLinePrefix + '{');
  const propertyNames = Object.keys(object);
  propertyNames.sort();
  for (let i = 0; i < propertyNames.length; ++i) {
    const prop = propertyNames[i];
    if (!object.hasOwnProperty(prop)) {
      continue;
    }
    const prefixWithName = '    ' + prefix + prop + ' : ';
    const propValue = object[prop];
    if (customFormatters && customFormatters[prop]) {
      const formatterName = customFormatters[prop];
      if (formatterName !== 'skip') {
        const formatter = formatters[formatterName];
        addResult(prefixWithName + formatter(propValue));
      }
    } else {
      dump(propValue, customFormatters, '    ' + prefix, prefixWithName);
    }
  }
  addResult(prefix + '}');
}

/**
 * @param {!Array} array
 * @param {!TestRunner.CustomFormatters=} customFormatters
 * @param {string=} prefix
 * @param {string=} firstLinePrefix
 */
export function addArray(array, customFormatters, prefix, firstLinePrefix) {
  prefix = prefix || '';
  firstLinePrefix = firstLinePrefix || prefix;
  addResult(firstLinePrefix + '[');
  for (let i = 0; i < array.length; ++i) {
    dump(array[i], customFormatters, prefix + '    ');
  }
  addResult(prefix + ']');
}

/**
 * @param {!Node} node
 */
export function dumpDeepInnerHTML(node) {
  /**
   * @param {string} prefix
   * @param {!Node} node
   */
  function innerHTML(prefix, node) {
    const openTag = [];
    if (node.nodeType === Node.TEXT_NODE) {
      if (!node.parentElement || node.parentElement.nodeName !== 'STYLE') {
        addResult(node.nodeValue);
      }
      return;
    }
    openTag.push('<' + node.nodeName);
    const attrs = node.attributes;
    for (let i = 0; attrs && i < attrs.length; ++i) {
      openTag.push(attrs[i].name + '=' + attrs[i].value);
    }

    openTag.push('>');
    addResult(prefix + openTag.join(' '));
    for (let child = node.firstChild; child; child = child.nextSibling) {
      innerHTML(prefix + '    ', child);
    }
    if (node.shadowRoot) {
      innerHTML(prefix + '    ', node.shadowRoot);
    }
    addResult(prefix + '</' + node.nodeName + '>');
  }
  innerHTML('', node);
}

/**
 * @param {!Node} node
 * @return {string}
 */
export function deepTextContent(node) {
  if (!node) {
    return '';
  }
  if (node.nodeType === Node.TEXT_NODE && node.nodeValue) {
    return !node.parentElement || node.parentElement.nodeName !== 'STYLE' ? node.nodeValue : '';
  }
  let res = '';
  const children = node.childNodes;
  for (let i = 0; i < children.length; ++i) {
    res += deepTextContent(children[i]);
  }
  if (node.shadowRoot) {
    res += deepTextContent(node.shadowRoot);
  }
  return res;
}

/**
 * @param {*} value
 * @param {!TestRunner.CustomFormatters=} customFormatters
 * @param {string=} prefix
 * @param {string=} prefixWithName
 */
export function dump(value, customFormatters, prefix, prefixWithName) {
  prefixWithName = prefixWithName || prefix;
  if (prefixWithName && prefixWithName.length > 80) {
    addResult(prefixWithName + 'was skipped due to prefix length limit');
    return;
  }
  if (value === null) {
    addResult(prefixWithName + 'null');
  } else if (value && value.constructor && value.constructor.name === 'Array') {
    addArray(/** @type {!Array} */ (value), customFormatters, prefix, prefixWithName);
  } else if (typeof value === 'object') {
    addObject(/** @type {!Object} */ (value), customFormatters, prefix, prefixWithName);
  } else if (typeof value === 'string') {
    addResult(prefixWithName + '"' + value + '"');
  } else {
    addResult(prefixWithName + value);
  }
}

/**
 * @param {!UI.TreeElement} treeElement
 */
export function dumpObjectPropertyTreeElement(treeElement) {
  const expandedSubstring = treeElement.expanded ? '[expanded]' : '[collapsed]';
  addResult(expandedSubstring + ' ' + treeElement.listItemElement.deepTextContent());

  for (let i = 0; i < treeElement.childCount(); ++i) {
    const property = treeElement.childAt(i).property;
    const key = property.name;
    const value = property.value._description;
    addResult('    ' + key + ': ' + value);
  }
}

/**
 * @param {symbol} eventName
 * @param {!Common.Object} obj
 * @param {function(?):boolean=} condition
 * @return {!Promise}
 */
export function waitForEvent(eventName, obj, condition) {
  condition = condition || function() {
    return true;
  };
  return new Promise(resolve => {
    obj.addEventListener(eventName, onEventFired);

    /**
     * @param {!Common.Event} event
     */
    function onEventFired(event) {
      if (!condition(event.data)) {
        return;
      }
      obj.removeEventListener(eventName, onEventFired);
      resolve(event.data);
    }
  });
}

/**
 * @param {function(!SDK.Target):boolean} filter
 * @return {!Promise<!SDK.Target>}
 */
export function waitForTarget(filter) {
  filter = filter || (target => true);
  for (const target of SDK.targetManager.targets()) {
    if (filter(target)) {
      return Promise.resolve(target);
    }
  }
  return new Promise(fulfill => {
    const observer = /** @type {!SDK.TargetManager.Observer} */ ({
      targetAdded: function(target) {
        if (filter(target)) {
          SDK.targetManager.unobserveTargets(observer);
          fulfill(target);
        }
      },
      targetRemoved: function() {},
    });
    SDK.targetManager.observeTargets(observer);
  });
}

/**
 * @param {!SDK.Target} targetToRemove
 * @return {!Promise<!SDK.Target>}
 */
export function waitForTargetRemoved(targetToRemove) {
  return new Promise(fulfill => {
    const observer = /** @type {!SDK.TargetManager.Observer} */ ({
      targetRemoved: function(target) {
        if (target === targetToRemove) {
          SDK.targetManager.unobserveTargets(observer);
          fulfill(target);
        }
      },
      targetAdded: function() {},
    });
    SDK.targetManager.observeTargets(observer);
  });
}

/**
 * @param {!SDK.RuntimeModel} runtimeModel
 * @return {!Promise}
 */
export function waitForExecutionContext(runtimeModel) {
  if (runtimeModel.executionContexts().length) {
    return Promise.resolve(runtimeModel.executionContexts()[0]);
  }
  return runtimeModel.once(SDK.RuntimeModel.Events.ExecutionContextCreated);
}

/**
 * @param {!SDK.ExecutionContext} context
 * @return {!Promise}
 */
export function waitForExecutionContextDestroyed(context) {
  const runtimeModel = context.runtimeModel;
  if (runtimeModel.executionContexts().indexOf(context) === -1) {
    return Promise.resolve();
  }
  return waitForEvent(
      SDK.RuntimeModel.Events.ExecutionContextDestroyed, runtimeModel,
      destroyedContext => destroyedContext === context);
}

/**
 * @param {number} a
 * @param {number} b
 * @param {string=} message
 */
export function assertGreaterOrEqual(a, b, message) {
  if (a < b) {
    addResult('FAILED: ' + (message ? message + ': ' : '') + a + ' < ' + b);
  }
}

let _pageLoadedCallback;

/**
 * @param {string} url
 * @param {function():void} callback
 */
export function navigate(url, callback) {
  _pageLoadedCallback = safeWrap(callback);
  TestRunner.resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.Load, _pageNavigated);
  // Note: injected <base> means that url is relative to test
  // and not the inspected page
  evaluateInPageAnonymously('window.location.replace(\'' + url + '\')');
}

/**
 * @return {!Promise}
 */
export function navigatePromise(url) {
  return new Promise(fulfill => navigate(url, fulfill));
}

export function _pageNavigated() {
  TestRunner.resourceTreeModel.removeEventListener(SDK.ResourceTreeModel.Events.Load, _pageNavigated);
  _handlePageLoaded();
}

/**
 * @param {function():void} callback
 */
export function hardReloadPage(callback) {
  _innerReloadPage(true, undefined, callback);
}

/**
 * @param {function():void} callback
 */
export function reloadPage(callback) {
  _innerReloadPage(false, undefined, callback);
}

/**
 * @param {(string|undefined)} injectedScript
 * @param {function():void} callback
 */
export function reloadPageWithInjectedScript(injectedScript, callback) {
  _innerReloadPage(false, injectedScript, callback);
}

/**
 * @return {!Promise}
 */
export function reloadPagePromise() {
  return new Promise(fulfill => reloadPage(fulfill));
}

/**
 * @param {boolean} hardReload
 * @param {(string|undefined)} injectedScript
 * @param {function():void} callback
 */
export function _innerReloadPage(hardReload, injectedScript, callback) {
  _pageLoadedCallback = safeWrap(callback);
  TestRunner.resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.Load, pageLoaded);
  TestRunner.resourceTreeModel.reloadPage(hardReload, injectedScript);
}

export function pageLoaded() {
  TestRunner.resourceTreeModel.removeEventListener(SDK.ResourceTreeModel.Events.Load, pageLoaded);
  addResult('Page reloaded.');
  _handlePageLoaded();
}

export async function _handlePageLoaded() {
  await waitForExecutionContext(/** @type {!SDK.RuntimeModel} */ (TestRunner.runtimeModel));
  if (_pageLoadedCallback) {
    const callback = _pageLoadedCallback;
    _pageLoadedCallback = undefined;
    callback();
  }
}

/**
 * @param {function():void} callback
 */
export function waitForPageLoad(callback) {
  TestRunner.resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.Load, onLoaded);

  function onLoaded() {
    TestRunner.resourceTreeModel.removeEventListener(SDK.ResourceTreeModel.Events.Load, onLoaded);
    callback();
  }
}

/**
 * @param {function():void} callback
 */
export function runWhenPageLoads(callback) {
  const oldCallback = _pageLoadedCallback;
  function chainedCallback() {
    if (oldCallback) {
      oldCallback();
    }
    callback();
  }
  _pageLoadedCallback = safeWrap(chainedCallback);
}

/**
 * @param {!Array<function(function():void)>} testSuite
 */
export function runTestSuite(testSuite) {
  const testSuiteTests = testSuite.slice();

  function runner() {
    if (!testSuiteTests.length) {
      completeTest();
      return;
    }
    const nextTest = testSuiteTests.shift();
    addResult('');
    addResult(
        'Running: ' +
        /function\s([^(]*)/.exec(nextTest)[1]);
    safeWrap(nextTest)(runner);
  }
  runner();
}

/**
 * @param {!Array<function():Promise<*>>} testSuite
 */
export async function runAsyncTestSuite(testSuite) {
  for (const nextTest of testSuite) {
    addResult('');
    addResult(
        'Running: ' +
        /function\s([^(]*)/.exec(nextTest)[1]);
    await safeAsyncWrap(nextTest)();
  }

  completeTest();
}

/**
 * @param {*} expected
 * @param {*} found
 * @param {string} message
 */
export function assertEquals(expected, found, message) {
  if (expected === found) {
    return;
  }

  let error;
  if (message) {
    error = 'Failure (' + message + '):';
  } else {
    error = 'Failure:';
  }
  throw new Error(error + ' expected <' + expected + '> found <' + found + '>');
}

/**
 * @param {*} found
 * @param {string} message
 */
export function assertTrue(found, message) {
  assertEquals(true, !!found, message);
}

/**
 * @param {!Object} receiver
 * @param {string} methodName
 * @param {!Function} override
 * @param {boolean=} opt_sticky
 * @return {!Function}
 */
export function override(receiver, methodName, override, opt_sticky) {
  override = safeWrap(override);

  const original = receiver[methodName];
  if (typeof original !== 'function') {
    throw new Error('Cannot find method to override: ' + methodName);
  }

  receiver[methodName] = function(var_args) {
    try {
      return override.apply(this, arguments);
    } catch (e) {
      throw new Error('Exception in overriden method \'' + methodName + '\': ' + e);
    } finally {
      if (!opt_sticky) {
        receiver[methodName] = original;
      }
    }
  };

  return original;
}

/**
 * @param {string} text
 * @return {string}
 */
export function clearSpecificInfoFromStackFrames(text) {
  let buffer = text.replace(/\(file:\/\/\/(?:[^)]+\)|[\w\/:-]+)/g, '(...)');
  buffer = buffer.replace(/\(http:\/\/(?:[^)]+\)|[\w\/:-]+)/g, '(...)');
  buffer = buffer.replace(/\(test:\/\/(?:[^)]+\)|[\w\/:-]+)/g, '(...)');
  buffer = buffer.replace(/\(<anonymous>:[^)]+\)/g, '(...)');
  buffer = buffer.replace(/VM\d+/g, 'VM');
  return buffer.replace(/\s*at[^()]+\(native\)/g, '');
}

export function hideInspectorView() {
  UI.inspectorView.element.setAttribute('style', 'display:none !important');
}

/**
 * @return {?SDK.ResourceTreeFrame}
 */
export function mainFrame() {
  return TestRunner.resourceTreeModel.mainFrame;
}

export class StringOutputStream {
  /**
   * @param {function(string):void} callback
   */
  constructor(callback) {
    this._callback = callback;
    this._buffer = '';
  }

  /**
   * @param {string} fileName
   * @return {!Promise<boolean>}
   */
  async open(fileName) {
    return true;
  }

  /**
   * @param {string} chunk
   */
  async write(chunk) {
    this._buffer += chunk;
  }

  async close() {
    this._callback(this._buffer);
  }
}

/**
 * @template V
 */
export class MockSetting {
  /**
   * @param {V} value
   */
  constructor(value) {
    this._value = value;
  }

  /**
   * @return {V}
   */
  get() {
    return this._value;
  }

  /**
   * @param {V} value
   */
  set(value) {
    this._value = value;
  }
}

/**
 * @return {!Array<!Root.Runtime.Module>}
 */
export function loadedModules() {
  return self.runtime._modules.filter(module => module._loadedForTest)
      .filter(module => module.name() !== 'help')
      .filter(module => module.name().indexOf('test_runner') === -1);
}

/**
 * @param {!Array<!Root.Runtime.Module>} relativeTo
 * @return {!Array<!Root.Runtime.Module>}
 */
export function dumpLoadedModules(relativeTo) {
  const previous = new Set(relativeTo || []);
  function moduleSorter(left, right) {
    return String.naturalOrderComparator(left._descriptor.name, right._descriptor.name);
  }

  addResult('Loaded modules:');
  const sortedLoadedModules = loadedModules().sort(moduleSorter);
  for (const module of sortedLoadedModules) {
    if (previous.has(module)) {
      continue;
    }
    addResult('    ' + module._descriptor.name);
  }
  return sortedLoadedModules;
}

/**
 * @param {string} urlSuffix
 * @param {!Workspace.projectTypes=} projectType
 * @return {!Promise}
 */
export function waitForUISourceCode(urlSuffix, projectType) {
  /**
   * @param {!Workspace.UISourceCode} uiSourceCode
   * @return {boolean}
   */
  function matches(uiSourceCode) {
    if (projectType && uiSourceCode.project().type() !== projectType) {
      return false;
    }
    if (!projectType && uiSourceCode.project().type() === Workspace.projectTypes.Service) {
      return false;
    }
    if (urlSuffix && !uiSourceCode.url().endsWith(urlSuffix)) {
      return false;
    }
    return true;
  }

  for (const uiSourceCode of Workspace.workspace.uiSourceCodes()) {
    if (urlSuffix && matches(uiSourceCode)) {
      return Promise.resolve(uiSourceCode);
    }
  }

  return waitForEvent(Workspace.Workspace.Events.UISourceCodeAdded, Workspace.workspace, matches);
}

/**
 * @param {!Function} callback
 */
export function waitForUISourceCodeRemoved(callback) {
  Workspace.workspace.once(Workspace.Workspace.Events.UISourceCodeRemoved).then(callback);
}

/**
 * @param {string=} url
 * @return {string}
 */
export function url(url = '') {
  const testScriptURL = /** @type {string} */ (Root.Runtime.queryParam('test'));

  // This handles relative (e.g. "../file"), root (e.g. "/resource"),
  // absolute (e.g. "http://", "data:") and empty (e.g. "") paths
  return new URL(url, testScriptURL + '/../').href;
}

/**
 * @param {string} str
 * @param {string} mimeType
 * @return {!Promise.<undefined>}
 * @suppressGlobalPropertiesCheck
 */
export function dumpSyntaxHighlight(str, mimeType) {
  const node = document.createElement('span');
  node.textContent = str;
  const javascriptSyntaxHighlighter = new UI.SyntaxHighlighter(mimeType, false);
  return javascriptSyntaxHighlighter.syntaxHighlightNode(node).then(dumpSyntax);

  function dumpSyntax() {
    const node_parts = [];

    for (let i = 0; i < node.childNodes.length; i++) {
      if (node.childNodes[i].getAttribute) {
        node_parts.push(node.childNodes[i].getAttribute('class'));
      } else {
        node_parts.push('*');
      }
    }

    addResult(str + ': ' + node_parts.join(', '));
  }
}

/**
 * @param {string} querySelector
 */
export async function dumpInspectedPageElementText(querySelector) {
  const value = await evaluateInPageAsync(`document.querySelector('${querySelector}').innerText`);
  addResult(value);
}

/** @type {boolean} */
let _startedTest = false;

/**
 * @implements {SDK.TargetManager.Observer}
 */
export class _TestObserver {
  /**
   * @param {!SDK.Target} target
   * @override
   */
  targetAdded(target) {
    if (target.id() === 'main') {
      _setupTestHelpers(target);
    }
    if (_startedTest) {
      return;
    }
    _startedTest = true;
    if (_isStartupTest()) {
      return;
    }
    TestRunner
        .loadHTML(`
      <head>
        <base href="${url()}">
      </head>
      <body>
      </body>
    `).then(() => _executeTestScript());
  }

  /**
   * @param {!SDK.Target} target
   * @override
   */
  targetRemoved(target) {
  }
}

(async function() {
  SDK.targetManager.observeTargets(new _TestObserver());
  if (!_isStartupTest()) {
    return;
  }
  /**
   * Startup test initialization:
   * 1. Wait for DevTools app UI to load
   * 2. Execute test script, the first line will be TestRunner.setupStartupTest(...) which:
   *    A. Navigate secondary window
   *    B. After preconditions occur, secondary window calls testRunner.inspectSecondaryWindow()
   * 3. Backend executes TestRunner._startupTestSetupFinished() which calls _initializeTarget()
   */
  TestRunner._initializeTargetForStartupTest =
      override(Main.Main._instanceForTest, '_initializeTarget', () => undefined).bind(Main.Main._instanceForTest);
  await addSnifferPromise(Main.Main._instanceForTest, '_showAppUI');
  _executeTestScript();
})();

/** @type {!{logToStderr: function(), navigateSecondaryWindow: function(string), notifyDone: function()}|undefined} */
self.testRunner;

TestRunner.StringOutputStream = StringOutputStream;
TestRunner.MockSetting = MockSetting;

TestRunner.formatters = formatters;

TestRunner.setupStartupTest = setupStartupTest;
TestRunner.flushResults = flushResults;
TestRunner.completeTest = completeTest;
TestRunner.addResult = addResult;
TestRunner.addResults = addResults;
TestRunner.runTests = runTests;
TestRunner.addSniffer = addSniffer;
TestRunner.addSnifferPromise = addSnifferPromise;
TestRunner.showPanel = showPanel;
TestRunner.createKeyEvent = createKeyEvent;
TestRunner.safeWrap = safeWrap;
TestRunner.safeAsyncWrap = safeAsyncWrap;
TestRunner.textContentWithLineBreaks = textContentWithLineBreaks;
TestRunner.textContentWithoutStyles = textContentWithoutStyles;
TestRunner.evaluateInPagePromise = evaluateInPagePromise;
TestRunner.callFunctionInPageAsync = callFunctionInPageAsync;
TestRunner.evaluateInPageWithTimeout = evaluateInPageWithTimeout;
TestRunner.evaluateFunctionInOverlay = evaluateFunctionInOverlay;
TestRunner.check = check;
TestRunner.deprecatedRunAfterPendingDispatches = deprecatedRunAfterPendingDispatches;
TestRunner.loadHTML = loadHTML;
TestRunner.addScriptTag = addScriptTag;
TestRunner.addStylesheetTag = addStylesheetTag;
TestRunner.addHTMLImport = addHTMLImport;
TestRunner.addIframe = addIframe;
TestRunner.markStep = markStep;
TestRunner.startDumpingProtocolMessages = startDumpingProtocolMessages;
TestRunner.addScriptForFrame = addScriptForFrame;
TestRunner.addObject = addObject;
TestRunner.addArray = addArray;
TestRunner.dumpDeepInnerHTML = dumpDeepInnerHTML;
TestRunner.deepTextContent = deepTextContent;
TestRunner.dump = dump;
TestRunner.dumpObjectPropertyTreeElement = dumpObjectPropertyTreeElement;
TestRunner.waitForEvent = waitForEvent;
TestRunner.waitForTarget = waitForTarget;
TestRunner.waitForTargetRemoved = waitForTargetRemoved;
TestRunner.waitForExecutionContext = waitForExecutionContext;
TestRunner.waitForExecutionContextDestroyed = waitForExecutionContextDestroyed;
TestRunner.assertGreaterOrEqual = assertGreaterOrEqual;
TestRunner.navigate = navigate;
TestRunner.navigatePromise = navigatePromise;
TestRunner.hardReloadPage = hardReloadPage;
TestRunner.reloadPage = reloadPage;
TestRunner.reloadPageWithInjectedScript = reloadPageWithInjectedScript;
TestRunner.reloadPagePromise = reloadPagePromise;
TestRunner.pageLoaded = pageLoaded;
TestRunner.waitForPageLoad = waitForPageLoad;
TestRunner.runWhenPageLoads = runWhenPageLoads;
TestRunner.runTestSuite = runTestSuite;
TestRunner.assertEquals = assertEquals;
TestRunner.assertTrue = assertTrue;
TestRunner.override = override;
TestRunner.clearSpecificInfoFromStackFrames = clearSpecificInfoFromStackFrames;
TestRunner.hideInspectorView = hideInspectorView;
TestRunner.mainFrame = mainFrame;
TestRunner.loadedModules = loadedModules;
TestRunner.dumpLoadedModules = dumpLoadedModules;
TestRunner.waitForUISourceCode = waitForUISourceCode;
TestRunner.waitForUISourceCodeRemoved = waitForUISourceCodeRemoved;
TestRunner.url = url;
TestRunner.dumpSyntaxHighlight = dumpSyntaxHighlight;
TestRunner.loadModule = loadModule;
TestRunner.evaluateInPageRemoteObject = evaluateInPageRemoteObject;
TestRunner.evaluateInPage = evaluateInPage;
TestRunner.evaluateInPageAnonymously = evaluateInPageAnonymously;
TestRunner.evaluateInPageAsync = evaluateInPageAsync;
TestRunner.deprecatedInitAsync = deprecatedInitAsync;
TestRunner.runAsyncTestSuite = runAsyncTestSuite;
TestRunner.dumpInspectedPageElementText = dumpInspectedPageElementText;

/**
 * @typedef {!Object<string, string>}
 */
TestRunner.CustomFormatters;
