// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

'use strict';

var Browser = require('..').Browser,
    By = require('..').By,
    logging = require('..').logging,
    assert = require('../testing/assert'),
    test = require('../lib/test');

test.suite(function(env) {
  // Logging API has numerous issues with PhantomJS:
  //   - does not support adjusting log levels for type "browser".
  //   - does not return proper log level for "browser" messages.
  //   - does not delete logs after retrieval
  // Logging API is not supported in IE.
  // Logging API not supported in Marionette.
  // Tests depend on opening data URLs, which is broken in Safari (issue 7586)
  test.ignore(env.browsers(
      Browser.PHANTOM_JS, Browser.IE, Browser.SAFARI, Browser.FIREFOX)).
  describe('logging', function() {
    var driver;

    test.beforeEach(function() {
      driver = null;
    });

    test.afterEach(function*() {
      if (driver) {
        return driver.quit();
      }
    });

    test.it('can be disabled', function*() {
      var prefs = new logging.Preferences();
      prefs.setLevel(logging.Type.BROWSER, logging.Level.OFF);

      driver = yield env.builder()
          .setLoggingPrefs(prefs)
          .buildAsync();

      yield driver.get(dataUrl(
          '<!DOCTYPE html><script>',
          'console.info("hello");',
          'console.warn("this is a warning");',
          'console.error("and this is an error");',
          '</script>'));
      return driver.manage().logs().get(logging.Type.BROWSER)
          .then(entries => assert(entries.length).equalTo(0));
    });

    // Firefox does not capture JS error console log messages.
    test.ignore(env.browsers(Browser.FIREFOX, 'legacy-firefox')).
    it('can be turned down', function*() {
      var prefs = new logging.Preferences();
      prefs.setLevel(logging.Type.BROWSER, logging.Level.SEVERE);

      driver = yield env.builder()
          .setLoggingPrefs(prefs)
          .buildAsync();

      yield driver.get(dataUrl(
          '<!DOCTYPE html><script>',
          'console.info("hello");',
          'console.warn("this is a warning");',
          'console.error("and this is an error");',
          '</script>'));
      return driver.manage().logs().get(logging.Type.BROWSER)
          .then(function(entries) {
            assert(entries.length).equalTo(1);
            assert(entries[0].level.name).equalTo('SEVERE');
            assert(entries[0].message).endsWith('and this is an error');
          });
    });

    // Firefox does not capture JS error console log messages.
    test.ignore(env.browsers(Browser.FIREFOX, 'legacy-firefox')).
    it('can be made verbose', function*() {
      var prefs = new logging.Preferences();
      prefs.setLevel(logging.Type.BROWSER, logging.Level.DEBUG);

      driver = yield env.builder()
          .setLoggingPrefs(prefs)
          .buildAsync();

      yield driver.get(dataUrl(
          '<!DOCTYPE html><script>',
          'console.debug("hello");',
          'console.warn("this is a warning");',
          'console.error("and this is an error");',
          '</script>'));
      return driver.manage().logs().get(logging.Type.BROWSER)
          .then(function(entries) {
            assert(entries.length).equalTo(3);
            assert(entries[0].level.name).equalTo('DEBUG');
            assert(entries[0].message).endsWith('hello');

            assert(entries[1].level.name).equalTo('WARNING');
            assert(entries[1].message).endsWith('this is a warning');

            assert(entries[2].level.name).equalTo('SEVERE');
            assert(entries[2].message).endsWith('and this is an error');
          });
    });

    // Firefox does not capture JS error console log messages.
    test.ignore(env.browsers(Browser.FIREFOX, 'legacy-firefox')).
    it('clears records after retrieval', function*() {
      var prefs = new logging.Preferences();
      prefs.setLevel(logging.Type.BROWSER, logging.Level.DEBUG);

      driver = yield env.builder()
          .setLoggingPrefs(prefs)
          .buildAsync();

      yield driver.get(dataUrl(
          '<!DOCTYPE html><script>',
          'console.debug("hello");',
          'console.warn("this is a warning");',
          'console.error("and this is an error");',
          '</script>'));
      yield driver.manage().logs().get(logging.Type.BROWSER)
          .then(entries => assert(entries.length).equalTo(3));
      return driver.manage().logs().get(logging.Type.BROWSER)
          .then(entries => assert(entries.length).equalTo(0));
    });

    test.it('does not mix log types', function*() {
      var prefs = new logging.Preferences();
      prefs.setLevel(logging.Type.BROWSER, logging.Level.DEBUG);
      prefs.setLevel(logging.Type.DRIVER, logging.Level.SEVERE);

      driver = yield env.builder()
          .setLoggingPrefs(prefs)
          .buildAsync();

      yield driver.get(dataUrl(
          '<!DOCTYPE html><script>',
          'console.debug("hello");',
          'console.warn("this is a warning");',
          'console.error("and this is an error");',
          '</script>'));
      return driver.manage().logs().get(logging.Type.DRIVER)
          .then(entries => assert(entries.length).equalTo(0));
    });
  });

  function dataUrl(var_args) {
    return 'data:text/html,'
        + Array.prototype.slice.call(arguments, 0).join('');
  }
});

@@ -3196,34 +3196,38 @@
 0%5D.message).
-endsWith('
+matches(/.*%5C%22?
 and this is 
@@ -3226,33 +3226,36 @@
 this is an error
-'
+%5C%22?/
 );%0A          %7D);
@@ -4122,24 +4122,31 @@
 ge).
-endsWith('
+matches(/.*%5C%22?
 hello
-'
+%5C%22?/
 );%0A%0A
@@ -4246,26 +4246,30 @@
 essage).
-endsWith('
+matches(/.*%5C%22?
 this is 
@@ -4277,17 +4277,20 @@
  warning
-'
+%5C%22?/
 );%0A%0A    
@@ -4389,18 +4389,22 @@
 ge).
-endsWith('
+matches(/.*%5C%22?
 and 
@@ -4419,17 +4419,20 @@
 an error
-'
+%5C%22?/
 );%0A     

Update a test to handle changes to the way chromedriver returns captured log messages