<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

var gProductData = {
  firefox: {
    name: "Firefox Desktop",
    full: "Firefox",
    abbr: "ff",
    channels: {
      nightly: {
        name: "Nightly",
        version: "13.0a1",
        adu: { low: 100, min: 70 }, // k ADUs
        rate: { high: 2, max: 3 }, // crashes per 100 ADU
        startup: { high: 20, max: 30 }, // percent of total crashes
        flashhang: { high: 20, max: 30 }, // total Flash hangs
        flashcrash: { high: 3, max: 5 }, // percentage of crashes that comes from Flash
      },
      aurora: {
        name: "Aurora",
        version: "12.0a2",
        adu: { low: 1000, min: 125 },
        rate: { high: 2, max: 2.5 },
        startup: { high: 20, max: 30 },
        flashhang: { high: 100, max: 150 },
        flashcrash: { high: 4, max: 7 },
      },
      beta: {
        name: "Beta",
        version: "11.0b3",
        appendver: true,
        adu: { low: 10000, min: 1000 },
        rate: { high: 2, max: 2.5 },
        startup: { high: 20, max: 25 },
        flashhang: { high: 500, max: 700 },
        flashcrash: { high: 5, max: 7 },
      },
      release: {
        name: "Release",
        version: "10.0.2",
        appendver: true,
        adu: { low: 100000, min: 10000 },
        rate: { factor: 10, high: 2, max: 2.5 },
        startup: { high: 15, max: 20 },
        flashhang: { high: 15000, max: 20000 },
        flashcrash: { high: 10, max: 13 },
      },
    },
  },
  fennec: {
    name: "Mobile (XUL)",
    full: "Fennec",
    abbr: "fn",
    noflash: true,
    channels: {
      nightly: {
        name: "Nightly",
        version: "13.0a1",
        adu: { low: 1, min: .1 },
        rate: { high: 2, max: 3 },
        startup: { high: 20, max: 30 },
        flashhang: { high: 20, max: 30 },
        flashcrash: { high: 3, max: 5 },
      },
      aurora: {
        name: "Aurora",
        version: "12.0a2",
        adu: { low: 1, min: .1 },
        rate: { high: 2, max: 2.5 },
        startup: { high: 20, max: 30 },
        flashhang: { high: 100, max: 150 },
        flashcrash: { high: 4, max: 7 },
      },
      beta: {
        name: "Beta",
        version: "11.0b3",
        appendver: true,
        adu: { low: 100, min: 10 },
        rate: { high: 2, max: 2.5 },
        startup: { high: 20, max: 25 },
        flashhang: { high: 500, max: 700 },
        flashcrash: { high: 5, max: 7 },
      },
      release: {
        name: "Release",
        version: "10.0",
        appendver: true,
        adu: { low: 500, min: 100 },
        rate: { high: 2, max: 2.5 },
        startup: { high: 15, max: 20 },
        flashhang: { high: 15000, max: 20000 },
        flashcrash: { high: 10, max: 13 },
      },
    },
  },
  fennecandroid: {
    name: "Fennec Android (native)",
    full: "FennecAndroid",
    abbr: "fna",
    noflash: true,
    channels: {
      nightly: {
        name: "Nightly",
        version: "13.0a1",
        adu: { low: 1, min: .1 },
        rate: { high: 2, max: 3 },
        startup: { high: 20, max: 30 },
        flashhang: { high: 20, max: 30 },
        flashcrash: { high: 3, max: 5 },
      },
      aurora: {
        name: "Aurora",
        version: "12.0a2",
        adu: { low: 10, min: 1 },
        rate: { high: 2, max: 2.5 },
        startup: { high: 20, max: 25 },
        flashhang: { high: 100, max: 150 },
        flashcrash: { high: 4, max: 7 },
      },
      beta: {
        name: "Beta",
        version: "11.0b3",
        appendver: true,
        adu: { low: 100, min: 10 },
        rate: { high: 2, max: 2.5 },
        startup: { high: 20, max: 25 },
        flashhang: { high: 500, max: 700 },
        flashcrash: { high: 5, max: 7 },
      },
    },
  },
};

var gSources = {
  adu: {
    precision: 0,
    unit: "k",
    lowLimits: true,
    getDataFile: function(aProd, aChannel) {
      return gAnalysisPath + aProd.full + "-daily.json";
    },
    getValue: function(aProd, aChannel, aCallback, aCBData) {
      fetchFile(this.getDataFile(aProd, aChannel), "json",
          function(aData) {
            if (!aData || !aData[gDay])
              aCallback(null, aCBData);
            else
              aCallback(aData[aProd.channels[aChannel].version][gDay].adu / 1000,
                        aCBData);
          }
      );
    },
  },
  rate: {
    precision: 2,
    unit: "",
    lowLimits: false,
    getCrashesFile: function(aProd, aChannel) {
      return gAnalysisPath + gDay + "/" + aProd.abbr + "-" +
             majVer(aProd.channels[aChannel].version) + "-total.csv";
    },
    getADUFile: function(aProd, aChannel) {
      return gAnalysisPath + gDay + "/" + aProd.abbr + "-" +
             majVer(aProd.channels[aChannel].version) + "-adu.csv";
    },
    getValue: function(aProd, aChannel, aCallback, aCBData) {
      var src = this;
      fetchFile(src.getCrashesFile(aProd, aChannel), "",
          function(aCrashes) {
            if (!aCrashes)
              aCallback(null, aCBData);
            fetchFile(src.getADUFile(aProd, aChannel), "",
                function(aADU) {
                  if (!aADU)
                    aCallback(null, aCBData);
                  else
                    aCallback(aCrashes / aADU * 100 *
                                (aProd.channels[aChannel].rate.factor ?
                                 aProd.channels[aChannel].rate.factor :
                                 1),
                              aCBData);
                }
            );
          }
      );
    },
  },
  startup: {
    precision: 0,
    unit: "%",
    lowLimits: false,
    getStartupFile: function(aProd, aChannel) {
      if (aProd.channels[aChannel].appendver)
        return gAnalysisPath + aProd.abbr + "-" + aChannel + "-" +
               repVer(aProd.channels[aChannel].version) + ".startup.json";
      else
        return gAnalysisPath + aProd.abbr + "-" + aChannel + ".startup.json";
    },
    getValue: function(aProd, aChannel, aCallback, aCBData) {
      fetchFile(this.getStartupFile(aProd, aChannel), "json",
          function(aData) {
            if (!aData || !aData[gDay])
              aCallback(null, aCBData);
            else
              aCallback(aData[gDay].startup.browser ?
                        aData[gDay].startup.browser / aData[gDay].total * 100 :
                        0, aCBData);
          }
      );
    },
  },
  flashhang: {
    precision: 0,
    unit: "",
    lowLimits: false,
    getFlashHangFile: function(aProd, aChannel) {
      return gAnalysisPath + aProd.abbr + "-" +
             repVer(aProd.channels[aChannel].version) + ".flashhang.json";
    },
    getValue: function(aProd, aChannel, aCallback, aCBData) {
      fetchFile(this.getFlashHangFile(aProd, aChannel), "json",
          function(aData) {
            if (!aData || !aData[gDay])
              aCallback(null, aCBData);
            else
              aCallback(aData[gDay].total_flash.hang, aCBData);
          }
      );
    },
  },
  flashcrash: {
    precision: 1,
    unit: "%",
    lowLimits: false,
    getFlashHangFile: function(aProd, aChannel) {
      return gAnalysisPath + aProd.abbr + "-" +
             repVer(aProd.channels[aChannel].version) + ".flashhang.json";
    },
    getValue: function(aProd, aChannel, aCallback, aCBData) {
      fetchFile(this.getFlashHangFile(aProd, aChannel), "json",
          function(aData) {
            if (!aData || !aData[gDay])
              aCallback(null, aCBData);
            else
              aCallback(aData[gDay].total_flash.crash / aData[gDay].total.crash * 100,
                        aCBData);
          }
      );
    },
  },
}

var gDebug, gLog;
var gDay;
//var gAnalysisPath = "https://crash-analysis.mozilla.com/rkaiser/";
var gAnalysisPath = "../../";

window.onload = function() {
  gDebug = document.getElementById("debug");
  gLog = document.getElementById("debugLog");

  // Get date to analyze.
  var anadate = new Date();
  anadate.setDate(anadate.getDate() - 1); // yesterday
  if (anadate.getUTCHours() < 14)
    anadate.setDate(anadate.getDate() - 1); // the day before
  // Format the date for ISO. Phew.
  gDay = anadate.getUTCFullYear() + "-";
  if (anadate.getUTCMonth() < 9)
    gDay += "0";
  gDay += (anadate.getUTCMonth() + 1) + "-";
  if (anadate.getUTCDate() < 10)
    gDay += "0";
  gDay += anadate.getUTCDate();
  document.getElementById("repDay").textContent = gDay;

  processData();
}

function processData() {
  var db = document.getElementById("dashboard");
  var baseSection = document.getElementById("none");
  for (var product in gProductData) {
    var sect = db.appendChild(baseSection.cloneNode(true));
    sect.setAttribute("id", product);
    var ptitle = sect.getElementsByTagName("h2")[0];
    ptitle.textContent = gProductData[product].name;

    for (var channel in gProductData[product].channels) {
      var cdata = gProductData[product].channels[channel];
      var headrow = sect.getElementsByClassName("headers")[0];
      headrow.appendChild(createCell(cdata.name, true));
      var versionrow = sect.getElementsByClassName("versions")[0];
      versionrow.appendChild(createCell(cdata.version));
      for (var source in gSources) {
        var sourcerow = sect.getElementsByClassName(source)[0];
        if (source.indexOf("flash") !== -1 && gProductData[product].noflash) {
          sourcerow.classList.add("hidden");
        }
        else {
          var sourceCell = sourcerow.appendChild(createCell(""));
          gSources[source].getValue(gProductData[product], channel, valueCallback,
              {cell: sourceCell, data: cdata, type: source});
        }
      }
      //gDebug.textContent = channel.name;
    }
  }
}

function createCell(aText, aHeader) {
  var cell = document.createElement(aHeader ? "th" : "td");
  cell.appendChild(document.createTextNode(aText));
  return cell;
}

function fetchFile(aURL, aFormat, aCallback) {
  var XHR = new XMLHttpRequest();
  XHR.onreadystatechange = function() {
    if (XHR.readyState == 4) {
      gLog.appendChild(document.createElement("li"))
          .appendChild(document.createTextNode(aURL + " - " + XHR.status +
                                               " " + XHR.statusText));
    }
    if (XHR.readyState == 4 && XHR.status == 200) {
      // so far so good
      if (XHR.responseXML != null && aFormat == "xml" &&
          XHR.responseXML.getElementById('test').firstChild.data)
        aCallback(aXHR.responseXML.getElementById('test').firstChild.data);
      else if (XHR.responseText != null && aFormat == "json")
        aCallback(JSON.parse(XHR.responseText));
      else
        aCallback(XHR.responseText);
    } else if (XHR.readyState == 4 && XHR.status != 200) {
      // fetched the wrong page or network error...
      aCallback(null);
    }
  };
  XHR.open("GET", aURL);
  XHR.send();
}

function valueCallback(aValue, aCBData) {
  aCBData.data.current = aValue;
  if (aValue !== null) {
    aCBData.cell.textContent = aValue.toFixed(gSources[aCBData.type].precision);
    if (gSources[aCBData.type].unit)
      aCBData.cell.textContent += gSources[aCBData.type].unit;
    aCBData.cell.classList.add("num");
    if (((gSources[aCBData.type].lowLimits) &&
         (aValue < aCBData.data[aCBData.type].min)) ||
        (aValue > aCBData.data[aCBData.type].max))
      aCBData.cell.classList.add("faroff");
    else if (((gSources[aCBData.type].lowLimits) &&
              (aValue < aCBData.data[aCBData.type].low)) ||
             (aValue > aCBData.data[aCBData.type].high))
      aCBData.cell.classList.add("outside");
    else
      aCBData.cell.classList.add("normal");
  }
  else {
    aCBData.cell.textContent = "ERR";
    aCBData.cell.classList.add("fail");
  }
}

function majVer(aVersion) {
  // returns major version, e.g. 11 for 11.0b3, 13 for 13.0a1, 10 for 10.0.2
  return aVersion.match(/^\d+/);
}

function repVer(aVersion) {
  // returns a report version, e.g. 11.0 for 11.0b3, 13.0a1 for 13.0a1, 10.0 for 10.0.2
  return aVersion.match(/^\d+\.[\da]+/);
}

function intVer(aVersion) {
  // returns the internal version, e.g. 11.0 for 11.0b3, 13.0a1 for 13.0a1, 10.0.2 for 10.0.2
  return aVersion.match(/^[\d\.a]+/);
}
<commit_msg>set current in the right place<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

var gProductData = {
  firefox: {
    name: "Firefox Desktop",
    full: "Firefox",
    abbr: "ff",
    channels: {
      nightly: {
        name: "Nightly",
        version: "13.0a1",
        adu: { low: 100, min: 70 }, // k ADUs
        rate: { high: 2, max: 3 }, // crashes per 100 ADU
        startup: { high: 20, max: 30 }, // percent of total crashes
        flashhang: { high: 20, max: 30 }, // total Flash hangs
        flashcrash: { high: 3, max: 5 }, // percentage of crashes that comes from Flash
      },
      aurora: {
        name: "Aurora",
        version: "12.0a2",
        adu: { low: 1000, min: 125 },
        rate: { high: 2, max: 2.5 },
        startup: { high: 20, max: 30 },
        flashhang: { high: 100, max: 150 },
        flashcrash: { high: 4, max: 7 },
      },
      beta: {
        name: "Beta",
        version: "11.0b3",
        appendver: true,
        adu: { low: 10000, min: 1000 },
        rate: { high: 2, max: 2.5 },
        startup: { high: 20, max: 25 },
        flashhang: { high: 500, max: 700 },
        flashcrash: { high: 5, max: 7 },
      },
      release: {
        name: "Release",
        version: "10.0.2",
        appendver: true,
        adu: { low: 100000, min: 10000 },
        rate: { factor: 10, high: 2, max: 2.5 },
        startup: { high: 15, max: 20 },
        flashhang: { high: 15000, max: 20000 },
        flashcrash: { high: 10, max: 13 },
      },
    },
  },
  fennec: {
    name: "Mobile (XUL)",
    full: "Fennec",
    abbr: "fn",
    noflash: true,
    channels: {
      nightly: {
        name: "Nightly",
        version: "13.0a1",
        adu: { low: 1, min: .1 },
        rate: { high: 2, max: 3 },
        startup: { high: 20, max: 30 },
        flashhang: { high: 20, max: 30 },
        flashcrash: { high: 3, max: 5 },
      },
      aurora: {
        name: "Aurora",
        version: "12.0a2",
        adu: { low: 1, min: .1 },
        rate: { high: 2, max: 2.5 },
        startup: { high: 20, max: 30 },
        flashhang: { high: 100, max: 150 },
        flashcrash: { high: 4, max: 7 },
      },
      beta: {
        name: "Beta",
        version: "11.0b3",
        appendver: true,
        adu: { low: 100, min: 10 },
        rate: { high: 2, max: 2.5 },
        startup: { high: 20, max: 25 },
        flashhang: { high: 500, max: 700 },
        flashcrash: { high: 5, max: 7 },
      },
      release: {
        name: "Release",
        version: "10.0",
        appendver: true,
        adu: { low: 500, min: 100 },
        rate: { high: 2, max: 2.5 },
        startup: { high: 15, max: 20 },
        flashhang: { high: 15000, max: 20000 },
        flashcrash: { high: 10, max: 13 },
      },
    },
  },
  fennecandroid: {
    name: "Fennec Android (native)",
    full: "FennecAndroid",
    abbr: "fna",
    noflash: true,
    channels: {
      nightly: {
        name: "Nightly",
        version: "13.0a1",
        adu: { low: 1, min: .1 },
        rate: { high: 2, max: 3 },
        startup: { high: 20, max: 30 },
        flashhang: { high: 20, max: 30 },
        flashcrash: { high: 3, max: 5 },
      },
      aurora: {
        name: "Aurora",
        version: "12.0a2",
        adu: { low: 10, min: 1 },
        rate: { high: 2, max: 2.5 },
        startup: { high: 20, max: 25 },
        flashhang: { high: 100, max: 150 },
        flashcrash: { high: 4, max: 7 },
      },
      beta: {
        name: "Beta",
        version: "11.0b3",
        appendver: true,
        adu: { low: 100, min: 10 },
        rate: { high: 2, max: 2.5 },
        startup: { high: 20, max: 25 },
        flashhang: { high: 500, max: 700 },
        flashcrash: { high: 5, max: 7 },
      },
    },
  },
};

var gSources = {
  adu: {
    precision: 0,
    unit: "k",
    lowLimits: true,
    getDataFile: function(aProd, aChannel) {
      return gAnalysisPath + aProd.full + "-daily.json";
    },
    getValue: function(aProd, aChannel, aCallback, aCBData) {
      fetchFile(this.getDataFile(aProd, aChannel), "json",
          function(aData) {
            if (!aData || !aData[gDay])
              aCallback(null, aCBData);
            else
              aCallback(aData[aProd.channels[aChannel].version][gDay].adu / 1000,
                        aCBData);
          }
      );
    },
  },
  rate: {
    precision: 2,
    unit: "",
    lowLimits: false,
    getCrashesFile: function(aProd, aChannel) {
      return gAnalysisPath + gDay + "/" + aProd.abbr + "-" +
             majVer(aProd.channels[aChannel].version) + "-total.csv";
    },
    getADUFile: function(aProd, aChannel) {
      return gAnalysisPath + gDay + "/" + aProd.abbr + "-" +
             majVer(aProd.channels[aChannel].version) + "-adu.csv";
    },
    getValue: function(aProd, aChannel, aCallback, aCBData) {
      var src = this;
      fetchFile(src.getCrashesFile(aProd, aChannel), "",
          function(aCrashes) {
            if (!aCrashes)
              aCallback(null, aCBData);
            fetchFile(src.getADUFile(aProd, aChannel), "",
                function(aADU) {
                  if (!aADU)
                    aCallback(null, aCBData);
                  else
                    aCallback(aCrashes / aADU * 100 *
                                (aProd.channels[aChannel].rate.factor ?
                                 aProd.channels[aChannel].rate.factor :
                                 1),
                              aCBData);
                }
            );
          }
      );
    },
  },
  startup: {
    precision: 0,
    unit: "%",
    lowLimits: false,
    getStartupFile: function(aProd, aChannel) {
      if (aProd.channels[aChannel].appendver)
        return gAnalysisPath + aProd.abbr + "-" + aChannel + "-" +
               repVer(aProd.channels[aChannel].version) + ".startup.json";
      else
        return gAnalysisPath + aProd.abbr + "-" + aChannel + ".startup.json";
    },
    getValue: function(aProd, aChannel, aCallback, aCBData) {
      fetchFile(this.getStartupFile(aProd, aChannel), "json",
          function(aData) {
            if (!aData || !aData[gDay])
              aCallback(null, aCBData);
            else
              aCallback(aData[gDay].startup.browser ?
                        aData[gDay].startup.browser / aData[gDay].total * 100 :
                        0, aCBData);
          }
      );
    },
  },
  flashhang: {
    precision: 0,
    unit: "",
    lowLimits: false,
    getFlashHangFile: function(aProd, aChannel) {
      return gAnalysisPath + aProd.abbr + "-" +
             repVer(aProd.channels[aChannel].version) + ".flashhang.json";
    },
    getValue: function(aProd, aChannel, aCallback, aCBData) {
      fetchFile(this.getFlashHangFile(aProd, aChannel), "json",
          function(aData) {
            if (!aData || !aData[gDay])
              aCallback(null, aCBData);
            else
              aCallback(aData[gDay].total_flash.hang, aCBData);
          }
      );
    },
  },
  flashcrash: {
    precision: 1,
    unit: "%",
    lowLimits: false,
    getFlashHangFile: function(aProd, aChannel) {
      return gAnalysisPath + aProd.abbr + "-" +
             repVer(aProd.channels[aChannel].version) + ".flashhang.json";
    },
    getValue: function(aProd, aChannel, aCallback, aCBData) {
      fetchFile(this.getFlashHangFile(aProd, aChannel), "json",
          function(aData) {
            if (!aData || !aData[gDay])
              aCallback(null, aCBData);
            else
              aCallback(aData[gDay].total_flash.crash / aData[gDay].total.crash * 100,
                        aCBData);
          }
      );
    },
  },
}

var gDebug, gLog;
var gDay;
//var gAnalysisPath = "https://crash-analysis.mozilla.com/rkaiser/";
var gAnalysisPath = "../../";

window.onload = function() {
  gDebug = document.getElementById("debug");
  gLog = document.getElementById("debugLog");

  // Get date to analyze.
  var anadate = new Date();
  anadate.setDate(anadate.getDate() - 1); // yesterday
  if (anadate.getUTCHours() < 14)
    anadate.setDate(anadate.getDate() - 1); // the day before
  // Format the date for ISO. Phew.
  gDay = anadate.getUTCFullYear() + "-";
  if (anadate.getUTCMonth() < 9)
    gDay += "0";
  gDay += (anadate.getUTCMonth() + 1) + "-";
  if (anadate.getUTCDate() < 10)
    gDay += "0";
  gDay += anadate.getUTCDate();
  document.getElementById("repDay").textContent = gDay;

  processData();
}

function processData() {
  var db = document.getElementById("dashboard");
  var baseSection = document.getElementById("none");
  for (var product in gProductData) {
    var sect = db.appendChild(baseSection.cloneNode(true));
    sect.setAttribute("id", product);
    var ptitle = sect.getElementsByTagName("h2")[0];
    ptitle.textContent = gProductData[product].name;

    for (var channel in gProductData[product].channels) {
      var cdata = gProductData[product].channels[channel];
      var headrow = sect.getElementsByClassName("headers")[0];
      headrow.appendChild(createCell(cdata.name, true));
      var versionrow = sect.getElementsByClassName("versions")[0];
      versionrow.appendChild(createCell(cdata.version));
      for (var source in gSources) {
        var sourcerow = sect.getElementsByClassName(source)[0];
        if (source.indexOf("flash") !== -1 && gProductData[product].noflash) {
          sourcerow.classList.add("hidden");
        }
        else {
          var sourceCell = sourcerow.appendChild(createCell(""));
          gSources[source].getValue(gProductData[product], channel, valueCallback,
              {cell: sourceCell, data: cdata, type: source});
        }
      }
      //gDebug.textContent = channel.name;
    }
  }
}

function createCell(aText, aHeader) {
  var cell = document.createElement(aHeader ? "th" : "td");
  cell.appendChild(document.createTextNode(aText));
  return cell;
}

function fetchFile(aURL, aFormat, aCallback) {
  var XHR = new XMLHttpRequest();
  XHR.onreadystatechange = function() {
    if (XHR.readyState == 4) {
      gLog.appendChild(document.createElement("li"))
          .appendChild(document.createTextNode(aURL + " - " + XHR.status +
                                               " " + XHR.statusText));
    }
    if (XHR.readyState == 4 && XHR.status == 200) {
      // so far so good
      if (XHR.responseXML != null && aFormat == "xml" &&
          XHR.responseXML.getElementById('test').firstChild.data)
        aCallback(aXHR.responseXML.getElementById('test').firstChild.data);
      else if (XHR.responseText != null && aFormat == "json")
        aCallback(JSON.parse(XHR.responseText));
      else
        aCallback(XHR.responseText);
    } else if (XHR.readyState == 4 && XHR.status != 200) {
      // fetched the wrong page or network error...
      aCallback(null);
    }
  };
  XHR.open("GET", aURL);
  XHR.send();
}

function valueCallback(aValue, aCBData) {
  aCBData.data[aCBData.type].current = aValue;
  if (aValue !== null) {
    aCBData.cell.textContent = aValue.toFixed(gSources[aCBData.type].precision);
    if (gSources[aCBData.type].unit)
      aCBData.cell.textContent += gSources[aCBData.type].unit;
    aCBData.cell.classList.add("num");
    if (((gSources[aCBData.type].lowLimits) &&
         (aValue < aCBData.data[aCBData.type].min)) ||
        (aValue > aCBData.data[aCBData.type].max))
      aCBData.cell.classList.add("faroff");
    else if (((gSources[aCBData.type].lowLimits) &&
              (aValue < aCBData.data[aCBData.type].low)) ||
             (aValue > aCBData.data[aCBData.type].high))
      aCBData.cell.classList.add("outside");
    else
      aCBData.cell.classList.add("normal");
  }
  else {
    aCBData.cell.textContent = "ERR";
    aCBData.cell.classList.add("fail");
  }
}

function majVer(aVersion) {
  // returns major version, e.g. 11 for 11.0b3, 13 for 13.0a1, 10 for 10.0.2
  return aVersion.match(/^\d+/);
}

function repVer(aVersion) {
  // returns a report version, e.g. 11.0 for 11.0b3, 13.0a1 for 13.0a1, 10.0 for 10.0.2
  return aVersion.match(/^\d+\.[\da]+/);
}

function intVer(aVersion) {
  // returns the internal version, e.g. 11.0 for 11.0b3, 13.0a1 for 13.0a1, 10.0.2 for 10.0.2
  return aVersion.match(/^[\d\.a]+/);
}
<|endoftext|>


<commit_before>// Class Screen defines canvas part of YouTyping.
// One YouTyping have only one Screen as child, and vice versa.
var Screen = function (canvas, youTyping) {
	var screen = this;

	var FPS = 0;

	this.canvas = canvas;

	// All notes and lines will be stored in this variable and managed
	// in key which represents index.
	this.items = {};

	this.setup = function (deferred) {
		paper.setup(screen.canvas);

		screen.cover = new paper.Path.Rectangle(paper.view.bounds);
		screen.cover.fillColor = 'black';
		screen.cover.fillColor.alpha = 0.7;

		screen.debugTexts = [];
		for (var i = 0; i < 5; i++) {
			var index = screen.debugTexts.push(new paper.PointText([20, 20 * (i + 1)]));
			screen.debugText = screen.debugTexts[index - 1];
			screen.debugText.justification = 'left';
			screen.debugText.fillColor = 'white';
		}

		setInterval(function () {
			screen.debugTexts[0].content = 'FPS: ' + FPS;
			FPS = 0;
			screen.debugTexts[2].content = 'Zerocall FPS: ' + youTyping.zeroCallFPS;
			youTyping.zeroCallFPS = 0; // not good
		}, 1000);

		logTrace('Screen is Set.');
		deferred.resolve();
	};

	this.load = function () {
		var settings = youTyping.settings;
		var now = youTyping.now;

		youTyping.zeroTime = now;
		screen.update();

		this.hitCircle = new paper.Path.Circle({
			center: [settings.hitPosition, settings.scoreYpos * settings.height],
			radius: settings.noteSize,
			strokeWidth: 1,
			strokeColor: 'white'
		});
	};

	this.ready = function () {
		screen.pressEnter = new paper.PointText({
			point: paper.view.bounds.bottomRight.multiply([0.5, 0.8]),
			content: 'Press enter.',
			justification: 'center',
			fontSize: 45,
			fillColor: 'white'
		});
		paper.tool.onKeyDown = function (event) {
			if (event.key === 'enter') {
				screen.pressEnter.remove();
				paper.tool.onKeyDown = null; // unbind
				screen.start();
			}
		};

		logTrace('Screen is Ready.');
	};

	this.start = function () {
		logTrace('Starting game.');

		paper.view.onFrame = function (event) {
			if (youTyping.player.getPlayerState() === 1) {
				screen.update();
			}
			screen.debugTexts[1].content = 'Measured Zero: ' + youTyping.estimatedZero.toFixed(2);
			screen.debugTexts[3].content = 'Active Objects: ' + paper.project.activeLayer.children.length;
			screen.debugTexts[4].content = 'Zero Time: ' + youTyping.zeroTime.toFixed(2);
			FPS++;
		};

		youTyping.play();
	};

	// layout notes and lines fitting to current time
	this.update = function () {
		var setting = youTyping.settings;
		var items = this.items;

		var now = youTyping.now;
		var runTime = (now - youTyping.zeroTime) / 1000;

		youTyping.score.forEach(function (item, index) {
			var Xpos = (item.time - runTime) * setting.speed + setting.hitPosition;
			if (index in items) { // if index-th item exists in screen
				if (item.emergeTime > runTime || item.vanishTime < runTime) {
					items[index].remove();
					delete items[index];
				} else {
					items[index].position.x = Xpos;
				}
			} else { // if index-th item doesn't exist in screen
				if (item.emergeTime <= runTime && item.vanishTime >= runTime) {
					items[index] = new paper.Group();

					// long line which devides score to measures
					if (item.type === '=') {
						items[index].addChild(new paper.Path.Line({
							from: [Xpos, setting.scoreYpos * setting.height - setting.longLineHeight / 2],
							to: [Xpos, setting.scoreYpos * setting.height + setting.longLineHeight / 2],
							strokeColor: 'white',
							strokeWidth: 2
						}));
					}
					// small line
					if (item.type === '-') {
						items[index].addChild(new paper.Path.Line({
							from: [Xpos, setting.scoreYpos * setting.height - setting.lineHeight / 2],
							to: [Xpos, setting.scoreYpos * setting.height + setting.lineHeight / 2],
							strokeColor: 'white',
							strokeWidth: 1
						}));
					}
					if (item.type === '+') {
						// note
						items[index].addChild(new paper.Path.Circle({
							center: [Xpos, setting.scoreYpos * setting.height],
							radius: setting.noteSize,
							strokeWidth: 1,
							strokeColor: '#aaa',
							fillColor: 'red'
						}));
						// lyric
						items[index].addChild(new paper.PointText({
							position: [Xpos, setting.scoreYpos * setting.height + setting.noteSize + 50],
							content: item.text,
							fillColor: 'white',
							justification: 'center',
							fontSize: 20,
							fontFamily: 'sans-serif'
						}));
					}
				}
			}
		});
	};
};<commit_msg>Enable starter by click<commit_after>// Class Screen defines canvas part of YouTyping.
// One YouTyping have only one Screen as child, and vice versa.
var Screen = function (canvas, youTyping) {
	var screen = this;

	var FPS = 0;

	this.canvas = canvas;

	// All notes and lines will be stored in this variable and managed
	// in key which represents index.
	this.items = {};

	this.setup = function (deferred) {
		paper.setup(screen.canvas);

		screen.cover = new paper.Path.Rectangle(paper.view.bounds);
		screen.cover.fillColor = 'black';
		screen.cover.fillColor.alpha = 0.7;

		screen.debugTexts = [];
		for (var i = 0; i < 5; i++) {
			var index = screen.debugTexts.push(new paper.PointText([20, 20 * (i + 1)]));
			screen.debugText = screen.debugTexts[index - 1];
			screen.debugText.justification = 'left';
			screen.debugText.fillColor = 'white';
		}

		setInterval(function () {
			screen.debugTexts[0].content = 'FPS: ' + FPS;
			FPS = 0;
			screen.debugTexts[2].content = 'Zerocall FPS: ' + youTyping.zeroCallFPS;
			youTyping.zeroCallFPS = 0; // not good
		}, 1000);

		logTrace('Screen is Set.');
		deferred.resolve();
	};

	this.load = function () {
		var settings = youTyping.settings;
		var now = youTyping.now;

		youTyping.zeroTime = now;
		screen.update();

		this.hitCircle = new paper.Path.Circle({
			center: [settings.hitPosition, settings.scoreYpos * settings.height],
			radius: settings.noteSize,
			strokeWidth: 1,
			strokeColor: 'white'
		});
	};

	this.ready = function () {
		screen.pressEnter = new paper.PointText({
			point: paper.view.bounds.bottomRight.multiply([0.5, 0.8]),
			content: 'Press enter or click.',
			justification: 'center',
			fontSize: 45,
			fillColor: 'white'
		});
		var triggerStartScreen = function (event) {
			if ((event.type === 'keydown' && event.key === 'enter') || event.type === 'mousedown') {
				screen.pressEnter.remove();
				paper.tool.onKeyDown = null; // unbind
				screen.start();
			}
		};
		paper.tool.onKeyDown = triggerStartScreen;
		screen.pressEnter.onMouseDown = triggerStartScreen;

		logTrace('Screen is Ready.');
	};

	this.start = function () {
		logTrace('Starting game.');

		paper.view.onFrame = function (event) {
			if (youTyping.player.getPlayerState() === 1) {
				screen.update();
			}
			screen.debugTexts[1].content = 'Measured Zero: ' + youTyping.estimatedZero.toFixed(2);
			screen.debugTexts[3].content = 'Active Objects: ' + paper.project.activeLayer.children.length;
			screen.debugTexts[4].content = 'Zero Time: ' + youTyping.zeroTime.toFixed(2);
			FPS++;
		};

		youTyping.play();
	};

	// layout notes and lines fitting to current time
	this.update = function () {
		var setting = youTyping.settings;
		var items = this.items;

		var now = youTyping.now;
		var runTime = (now - youTyping.zeroTime) / 1000;

		youTyping.score.forEach(function (item, index) {
			var Xpos = (item.time - runTime) * setting.speed + setting.hitPosition;
			if (index in items) { // if index-th item exists in screen
				if (item.emergeTime > runTime || item.vanishTime < runTime) {
					items[index].remove();
					delete items[index];
				} else {
					items[index].position.x = Xpos;
				}
			} else { // if index-th item doesn't exist in screen
				if (item.emergeTime <= runTime && item.vanishTime >= runTime) {
					items[index] = new paper.Group();

					// long line which devides score to measures
					if (item.type === '=') {
						items[index].addChild(new paper.Path.Line({
							from: [Xpos, setting.scoreYpos * setting.height - setting.longLineHeight / 2],
							to: [Xpos, setting.scoreYpos * setting.height + setting.longLineHeight / 2],
							strokeColor: 'white',
							strokeWidth: 2
						}));
					}
					// small line
					if (item.type === '-') {
						items[index].addChild(new paper.Path.Line({
							from: [Xpos, setting.scoreYpos * setting.height - setting.lineHeight / 2],
							to: [Xpos, setting.scoreYpos * setting.height + setting.lineHeight / 2],
							strokeColor: 'white',
							strokeWidth: 1
						}));
					}
					if (item.type === '+') {
						// note
						items[index].addChild(new paper.Path.Circle({
							center: [Xpos, setting.scoreYpos * setting.height],
							radius: setting.noteSize,
							strokeWidth: 1,
							strokeColor: '#aaa',
							fillColor: 'red'
						}));
						// lyric
						items[index].addChild(new paper.PointText({
							position: [Xpos, setting.scoreYpos * setting.height + setting.noteSize + 50],
							content: item.text,
							fillColor: 'white',
							justification: 'center',
							fontSize: 20,
							fontFamily: 'sans-serif'
						}));
					}
				}
			}
		});
	};
};
<|endoftext|>


<commit_before>'use strict';

var epgSearch = angular.module('epgSearch', []);

epgSearch.controller('EpgSearchController', ['$scope', '$timeout', 'search', function($scope, $timeout, search) {

  $scope.filterVal = "";

  $scope.searchOpened = false;
  $scope.searchClick = function($event) {
    $scope.searchOpened = !$scope.searchOpened;
  };

  $scope.searchForward = function() {
    $scope.resultsSummary = null;
    search.forward($scope.filterVal, $scope.guideData.curDate, $scope.showResult);
  };

  $scope.searchBackward = function() {
    $scope.resultsSummary = null;
    search.backward($scope.filterVal, $scope.guideData.curDate, $scope.showResult);
  };

  $scope.showResult = function(results) {
    $scope.resultsSummary = (results.index + 1) + ' / ' + results.programs.length;
    if (results.programs.length > 0) {
      var program = results.programs[results.index];
      var startTime = new Date(program.start);
      startTime.setMinutes(0);
      $scope.guideData.setStartTime(startTime);
      $scope.guideData.nextPage(program.id);
    }
  };

  $scope.isSearching = function() {
    return search.isBusy();
  };

  $scope.closeSearch = function() {
    $timeout(function() {
      $scope.fireEpgAction('search');
      document.getElementById('searchBtn').click();
    }, 5);
  };

  $scope.searchFilter = function(newValue) {
    if (newValue || newValue === '') {
      $scope.filterVal = newValue;
    }
    else {
      if (!$scope.guideData.isMyth28)
        return 'Available in MythTV 0.28';
      else if ($scope.guideData.demoMode)
        return 'Search not available in demo';
    }
    return $scope.filterVal;
  };
}]);

epgSearch.factory('search', ['$http', '$q', function($http, $q) {

  var busy = false;
  var encodedFilter;
  var results = {
    index: -1,
    programs: [],
    addPrograms: function(progs) {
      for (var i = 0; i < progs.length; i++) {
        var prog = progs[i];
        if (!this.hasProgram(prog)) {
          prog.start = new Date(prog.StartTime);
          prog.id = 'ch' + prog.Channel.ChanId + 'pr' + prog.StartTime;
          this.programs.push(prog);
        }
      }
    },
    hasProgram: function(prog) {
      for (var i = 0; i < this.programs.length; i++) {
        var program = this.programs[i];
        if (program.ChanId == prog.ChanId && program.StartTime == prog.StartTime)
          return true;
      }
    }
  };

  function doSearch(filter, curDate, callback) {
    busy = true;
    results.index = -1;
    results.programs = [];
    encodedFilter = filter;

    var startTime = new Date();
    var baseUrl = '/Guide/GetProgramList?StartTime=' + startTime.toISOString();
    console.log('search base url: ' + baseUrl);

    $q.all({
      // title search redundant with keyword search?
      // titleSearch: $http.get(baseUrl + '&TitleFilter=' + encodedFilter),
      personSearch: $http.get(baseUrl + '&PersonFilter=' + encodedFilter),
      keywordSearch: $http.get(baseUrl + '&KeywordFilter=' + encodedFilter)
    }).then(function(res) {

      busy = false;

      // console.log('titleSearch:\n============\n' + JSON.stringify(res.titleSearch.data, null, 2));
      // console.log('\npersonSearch:\n============\n' + JSON.stringify(res.personSearch.data, null, 2));
      // console.log('\nkeywordSearch:\n============\n' + JSON.stringify(res.personSearch.data, null, 2));

      // results.addPrograms(res.titleSearch.data.ProgramList.Programs);
      results.addPrograms(res.personSearch.data.ProgramList.Programs);
      results.addPrograms(res.keywordSearch.data.ProgramList.Programs);

      // initialize the index
      if (results.programs.length > 0) {
        results.index = 0;
        var prog = results.programs[results.index];
        var compareCurDate = new Date(curDate.getTime());
        compareCurDate.setMinutes(0);
        compareCurDate.setSeconds(0);
        compareCurDate.setMilliseconds(0);
        while (prog.start.getTime() < compareCurDate.getTime()) {
          results.index++;
          prog = results.programs[results.index];
        }
      }
      callback(results);
    });
  }

  return {
    forward: function(filter, curDate, callback) {
      if (!filter || filter === '')
        return;
      var newFilter = encodeURIComponent(filter);
      if (newFilter != encodedFilter) {
        doSearch(newFilter, curDate, callback);
      }
      if (results.programs.length > 0) {
        results.index++;
        if (results.index == results.programs.length)
          results.index = 0;
        callback(results);
      }
    },
    backward: function(filter, curDate, callback) {
      if (!filter || filter === '')
        return;
      var newFilter = encodeURIComponent(filter);
      if (newFilter != encodedFilter) {
        doSearch(newFilter, curDate, callback);
      }
      if (results.programs.length > 0) {
        results.index--;
        if (results.index == -1)
          results.index = results.programs.length - 1;
        callback(results);
      }
    },
    isBusy: function() {
      return busy;
    },
    getResults: function() {
      return results;
    }
  };
}]);

epgSearch.directive('searchPreRender', ['$timeout', function($timeout) {
  return {
    restrict: 'A',
    link: function link(scope, elem, attrs) {
      $timeout(function() {
        elem[0].click();
        elem[0].click();
      }, 5);
    }
  };
}]);
<commit_msg>Issue #11: Overlooked search results.<commit_after>'use strict';

var epgSearch = angular.module('epgSearch', []);

epgSearch.controller('EpgSearchController', ['$scope', '$timeout', 'search', function($scope, $timeout, search) {

  $scope.filterVal = "";

  $scope.searchOpened = false;
  $scope.searchClick = function($event) {
    $scope.searchOpened = !$scope.searchOpened;
  };

  $scope.searchForward = function() {
    $scope.resultsSummary = null;
    search.forward($scope.filterVal, $scope.guideData.curDate, $scope.showResult);
  };

  $scope.searchBackward = function() {
    $scope.resultsSummary = null;
    search.backward($scope.filterVal, $scope.guideData.curDate, $scope.showResult);
  };

  $scope.showResult = function(results) {
    $scope.resultsSummary = (results.index + 1) + ' / ' + results.programs.length;
    if (results.programs.length > 0) {
      var program = results.programs[results.index];
      var startTime = new Date(program.start);
      startTime.setMinutes(0);
      $scope.guideData.setStartTime(startTime);
      $scope.guideData.nextPage(program.id);
    }
  };

  $scope.isSearching = function() {
    return search.isBusy();
  };

  $scope.closeSearch = function() {
    $timeout(function() {
      $scope.fireEpgAction('search');
      document.getElementById('searchBtn').click();
    }, 5);
  };

  $scope.searchFilter = function(newValue) {
    if (newValue || newValue === '') {
      $scope.filterVal = newValue;
    }
    else {
      if (!$scope.guideData.isMyth28)
        return 'Available in MythTV 0.28';
      else if ($scope.guideData.demoMode)
        return 'Search not available in demo';
    }
    return $scope.filterVal;
  };
}]);

epgSearch.factory('search', ['$http', '$q', function($http, $q) {

  var busy = false;
  var encodedFilter;
  var results = {
    index: -1,
    programs: [],
    addPrograms: function(progs) {
      for (var i = 0; i < progs.length; i++) {
        var prog = progs[i];
        if (!this.hasProgram(prog)) {
          prog.start = new Date(prog.StartTime);
          prog.id = 'ch' + prog.Channel.ChanId + 'pr' + prog.StartTime;
          this.programs.push(prog);
        }
      }
    },
    hasProgram: function(prog) {
      for (var i = 0; i < this.programs.length; i++) {
        var program = this.programs[i];
        if (program.StartTime == prog.StartTime && program.Channel.ChanId == prog.Channel.ChanId)
          return true;
      }
      return false;
    }
  };

  function doSearch(filter, curDate, callback) {
    busy = true;
    results.index = -1;
    results.programs = [];
    encodedFilter = filter;

    var startTime = new Date();
    var baseUrl = '/Guide/GetProgramList?StartTime=' + startTime.toISOString();
    console.log('search base url: ' + baseUrl);

    $q.all({
      // title search redundant with keyword search?
      // titleSearch: $http.get(baseUrl + '&TitleFilter=' + encodedFilter),
      personSearch: $http.get(baseUrl + '&PersonFilter=' + encodedFilter),
      keywordSearch: $http.get(baseUrl + '&KeywordFilter=' + encodedFilter)
    }).then(function(res) {

      busy = false;

      // console.log('titleSearch:\n============\n' + JSON.stringify(res.titleSearch.data, null, 2));
      // console.log('\npersonSearch:\n============\n' + JSON.stringify(res.personSearch.data, null, 2));
      // console.log('\nkeywordSearch:\n============\n' + JSON.stringify(res.personSearch.data, null, 2));

      // results.addPrograms(res.titleSearch.data.ProgramList.Programs);
      results.addPrograms(res.personSearch.data.ProgramList.Programs);
      results.addPrograms(res.keywordSearch.data.ProgramList.Programs);

      // initialize the index
      if (results.programs.length > 0) {
        results.index = 0;
        var prog = results.programs[results.index];
        var compareCurDate = new Date(curDate.getTime());
        compareCurDate.setMinutes(0);
        compareCurDate.setSeconds(0);
        compareCurDate.setMilliseconds(0);
        while (prog.start.getTime() < compareCurDate.getTime()) {
          results.index++;
          prog = results.programs[results.index];
        }
      }
      callback(results);
    });
  }

  return {
    forward: function(filter, curDate, callback) {
      if (!filter || filter === '')
        return;
      var newFilter = encodeURIComponent(filter);
      if (newFilter != encodedFilter) {
        doSearch(newFilter, curDate, callback);
      }
      if (results.programs.length > 0) {
        results.index++;
        if (results.index == results.programs.length)
          results.index = 0;
        callback(results);
      }
    },
    backward: function(filter, curDate, callback) {
      if (!filter || filter === '')
        return;
      var newFilter = encodeURIComponent(filter);
      if (newFilter != encodedFilter) {
        doSearch(newFilter, curDate, callback);
      }
      if (results.programs.length > 0) {
        results.index--;
        if (results.index == -1)
          results.index = results.programs.length - 1;
        callback(results);
      }
    },
    isBusy: function() {
      return busy;
    },
    getResults: function() {
      return results;
    }
  };
}]);

epgSearch.directive('searchPreRender', ['$timeout', function($timeout) {
  return {
    restrict: 'A',
    link: function link(scope, elem, attrs) {
      $timeout(function() {
        elem[0].click();
        elem[0].click();
      }, 5);
    }
  };
}]);
<|endoftext|>


<commit_before>function runTest()
{
    FBTest.sysout("issue6402.START");

    FBTest.openNewTab(basePath + "console/6402/issue6402.html", function()
    {
        // Note: do NOT reload at this moment.
        FBTest.enableConsolePanel(function(wrappedWin)
        {
            var tasks = new FBTest.TaskList();
            var iframe = wrappedWin.document.querySelector("#iframe");

            // Note: Test for the FW.Firebug.getConsoleByGlobal() function.
            var oriIframeConsoleInstance = FW.Firebug.getConsoleByGlobal(iframe.contentWindow);

            tasks.push(reloadIframe, iframe);

            tasks.push(testGetConsoleByGlobal, iframe, oriIframeConsoleInstance);

            tasks.wrapAndPush(checkConsole, wrappedWin, "false", "window._console should NOT refer to "+
                "the exposed Firebug console");

            tasks.push(FBTest.reload);

            tasks.wrapAndPush(checkConsole, wrappedWin, "true", "window._console should refer to the "+
                "exposed Firebug console");

            tasks.push(checkConsoleXMLPage);

            tasks.run(function()
            {
                FBTestFirebug.testDone("issue6402.DONE");
            });
        });
    });
}

function checkConsole(win, expectedResult, message)
{
    var $id = win.document.getElementById.bind(win.document);
    $id("check").click();
    FBTest.compare(expectedResult, $id("equals").textContent, message);
}

function checkConsoleXMLPage(callback)
{
    FBTest.openURL(basePath + "console/6402/issue6402.xml", function(win)
    {
        FBTest.executeCommandAndVerify(callback, "window.console.log('ok');", "ok",
            "div", "logRow-log");
    });
}

function reloadIframe(callback, iframe)
{
    iframe.addEventListener("load", function onload()
    {
        FBTest.progress("iframe reloaded");
        iframe.removeEventListener("load", onload);
        callback();
    });
    iframe.contentWindow.location.reload();
}

// Tests the value returned by Firebug.getConsoleByGlobal();
function testGetConsoleByGlobal(callback, iframe, oriIframeConsoleInstance)
{
    var newIframeConsoleInstance = FW.Firebug.getConsoleByGlobal(iframe.contentWindow);
    FBTest.ok(newIframeConsoleInstance, "newIframeConsoleInstance should be non-null");
    FBTest.ok(oriIframeConsoleInstance, "oriIframeConsoleInstance should be non-null");
    FBTest.compare(newIframeConsoleInstance, oriIframeConsoleInstance,
        "newIframeConsoleInstance should be different from oriIframeConsoleInstance", true);
    callback();
}
<commit_msg>Actually fix console/6402 test<commit_after>function runTest()
{
    FBTest.sysout("issue6402.START");

    FBTest.openNewTab(basePath + "console/6402/issue6402.html", function(wrappedWin)
    {
        FBTest.openFirebug(function()
        {
            var tasks = new FBTest.TaskList();
            var iframe = wrappedWin.document.querySelector("#iframe");

            // Note: do NOT reload at this moment.
            FBTest.enableConsolePanel();

            // Note: Test for the FW.Firebug.getConsoleByGlobal() function.
            var oriIframeConsoleInstance = FW.Firebug.getConsoleByGlobal(iframe.contentWindow);

            tasks.push(reloadIframe, iframe);

            tasks.push(testGetConsoleByGlobal, iframe, oriIframeConsoleInstance);

            tasks.wrapAndPush(checkConsole, wrappedWin, "false", "window._console should NOT refer to "+
                "the exposed Firebug console");

            tasks.push(FBTest.reload);

            tasks.wrapAndPush(checkConsole, wrappedWin, "true", "window._console should refer to the "+
                "exposed Firebug console");

            tasks.push(checkConsoleXMLPage);

            tasks.run(function()
            {
                FBTestFirebug.testDone("issue6402.DONE");
            });

        });
    });
}

function checkConsole(win, expectedResult, message)
{
    var $id = win.document.getElementById.bind(win.document);
    $id("check").click();
    FBTest.compare(expectedResult, $id("equals").textContent, message);
}

function checkConsoleXMLPage(callback)
{
    FBTest.openURL(basePath + "console/6402/issue6402.xml", function(win)
    {
        FBTest.executeCommandAndVerify(callback, "window.console.log('ok');", "ok",
            "div", "logRow-log");
    });
}

function reloadIframe(callback, iframe)
{
    iframe.addEventListener("load", function onload()
    {
        FBTest.progress("iframe reloaded");
        iframe.removeEventListener("load", onload);
        callback();
    });
    iframe.contentWindow.location.reload();
}

// Tests the value returned by Firebug.getConsoleByGlobal();
function testGetConsoleByGlobal(callback, iframe, oriIframeConsoleInstance)
{
    var newIframeConsoleInstance = FW.Firebug.getConsoleByGlobal(iframe.contentWindow);
    FBTest.ok(newIframeConsoleInstance, "newIframeConsoleInstance should be non-null");
    FBTest.ok(oriIframeConsoleInstance, "oriIframeConsoleInstance should be non-null");
    FBTest.compare(newIframeConsoleInstance, oriIframeConsoleInstance,
        "newIframeConsoleInstance should be different from oriIframeConsoleInstance", true);
    callback();
}
<|endoftext|>


<commit_before>
import { E2EGlobal } from './helpers/E2EGlobal'
import { E2EApp } from './helpers/E2EApp'
import { E2EMeetingSeries } from './helpers/E2EMeetingSeries'
import { E2EMeetingSeriesEditor } from './helpers/E2EMeetingSeriesEditor'
import { E2EMinutes } from './helpers/E2EMinutes'

describe('MeetingSeries Editor', function () {
    const aProjectName = "E2E MeetingSeries Editor";
    let aMeetingCounter = 0;
    let aMeetingNameBase = "Meeting Name #";
    let aMeetingName;

    beforeEach("goto start page and make sure test user is logged in", function () {
        E2EApp.gotoStartPage();
        expect(browser.getTitle()).to.equal('4minitz!');
        expect (E2EApp.isLoggedIn()).to.be.true;

        aMeetingCounter++;
        aMeetingName = aMeetingNameBase + aMeetingCounter;
        E2EMeetingSeries.createMeetingSeries(aProjectName, aMeetingName);
    });

    it('can open and close meeting series editor without changing data', function () {
        E2EMeetingSeriesEditor.openMeetingSeriesEditor(aProjectName, aMeetingName);
        // Now dialog should be there
        expect(browser.isVisible('#btnMeetingSeriesSave')).to.be.true;
        browser.click('button.close');
        E2EGlobal.waitSomeTime(); // give dialog animation time
        // Now dialog should be gone
        expect(browser.isVisible('#btnMeetingSeriesSave')).to.be.false;
        expect(E2EMeetingSeries.getMeetingSeriesId(aProjectName, aMeetingName)).not.to.be.false;
    });

    it('can open and cancel meeting series editor without changing data', function () {
        E2EMeetingSeriesEditor.openMeetingSeriesEditor(aProjectName, aMeetingName);
        // Now dialog should be there
        expect(browser.isVisible('#btnMeetinSeriesEditCancel')).to.be.true;
        browser.click('#btnMeetinSeriesEditCancel');
        E2EGlobal.waitSomeTime(); // give dialog animation time
        // Now dialog should be gone
        expect(browser.isVisible('#btnMeetinSeriesEditCancel')).to.be.false;
        expect(E2EMeetingSeries.getMeetingSeriesId(aProjectName, aMeetingName)).not.to.be.false;
    });

    it('can delete an empty meeting series', function () {
        let countAfterCreate = E2EMeetingSeries.countMeetingSeries();
        expect(E2EMeetingSeries.getMeetingSeriesId(aProjectName, aMeetingName)).to.be.ok;
        E2EMeetingSeriesEditor.openMeetingSeriesEditor(aProjectName, aMeetingName);

        browser.click("#deleteMeetingSeries");
        E2EApp.confirmationDialogAnswer(true);

        expect(E2EMeetingSeries.countMeetingSeries()).to.equal(countAfterCreate -1);
        expect(E2EMeetingSeries.getMeetingSeriesId(aProjectName, aMeetingName)).not.to.be.ok;
    });

    it('can cancel delete of meeting series', function () {
        let countAfterCreate = E2EMeetingSeries.countMeetingSeries();
        expect(E2EMeetingSeries.getMeetingSeriesId(aProjectName, aMeetingName)).to.be.ok;
        E2EMeetingSeriesEditor.openMeetingSeriesEditor(aProjectName, aMeetingName);

        browser.click("#deleteMeetingSeries");
        E2EApp.confirmationDialogAnswer(false);

        expect(E2EMeetingSeries.countMeetingSeries()).to.equal(countAfterCreate);
        expect(E2EMeetingSeries.getMeetingSeriesId(aProjectName, aMeetingName)).to.be.ok;
    });

    it('can clean up child minutes on deleting meeting series', function () {
        let aMeetingName = "Meeting Name (with Minute)";
        let countDBMeetingSeriesBefore = server.call('e2e.countMeetingSeriesInMongDB');
        let countDBMinutesBefore = server.call('e2e.countMinutesInMongoDB');
        E2EMeetingSeries.createMeetingSeries(aProjectName, aMeetingName);
        E2EMinutes.addMinutesToMeetingSeries(aProjectName, aMeetingName);
        E2EMinutes.finalizeCurrentMinutes();
        E2EMeetingSeries.gotoMeetingSeries(aProjectName, aMeetingName);

        // One more Meeting series and one more minutes
        expect(server.call('e2e.countMeetingSeriesInMongDB')).to.equal(countDBMeetingSeriesBefore +1);
        expect(server.call('e2e.countMinutesInMongoDB')).to.equal(countDBMinutesBefore +1);

        // Now delete meeting series with attached Minutes
        E2EMeetingSeriesEditor.openMeetingSeriesEditor(aProjectName, aMeetingName);
        browser.click("#deleteMeetingSeries");
        E2EApp.confirmationDialogAnswer(true);

        // Meeting series and attached minutes should be gone
        expect(server.call('e2e.countMeetingSeriesInMongDB')).to.equal(countDBMeetingSeriesBefore);
        expect(server.call('e2e.countMinutesInMongoDB')).to.equal(countDBMinutesBefore);
        expect(E2EMeetingSeries.getMeetingSeriesId(aProjectName, aMeetingName)).not.to.be.ok;
    });

    it('can not save meeting series without project or name', function () {
        E2EMeetingSeriesEditor.openMeetingSeriesEditor(aProjectName, aMeetingName);
        browser.setValue('input[id="id_meetingproject"]', "");  // empty input
        browser.setValue('input[id="id_meetingname"]', "");     // empty input
        browser.click("#btnMeetingSeriesSave");     // try to save
        expect(browser.isVisible("#btnMeetingSeriesSave")).to.be.true;  // dialog still open!

        browser.setValue('input[id="id_meetingproject"]', "XXX");
        browser.setValue('input[id="id_meetingname"]', "");     // empty input
        browser.click("#btnMeetingSeriesSave");     // try to save
        expect(browser.isVisible("#btnMeetingSeriesSave")).to.be.true;  // dialog still open!

        browser.setValue('input[id="id_meetingproject"]', "");  // empty input
        browser.setValue('input[id="id_meetingname"]', "XXX");
        browser.click("#btnMeetingSeriesSave");     // try to save
        expect(browser.isVisible("#btnMeetingSeriesSave")).to.be.true;  // dialog still open!

        browser.click('#btnMeetinSeriesEditCancel');
        E2EGlobal.waitSomeTime(750); // give dialog animation time
        expect(E2EMeetingSeries.getMeetingSeriesId(aProjectName, aMeetingName)).to.be.ok;  // prj/name should be unchanged
    });

    it('can save meeting series with new project name and meeting name', function () {
        E2EMeetingSeriesEditor.openMeetingSeriesEditor(aProjectName, aMeetingName);
        let aNewProjectName = "E2E New Project";
        let aNewMeetingName = "New Meeting Name";
        browser.setValue('input[id="id_meetingproject"]', aNewProjectName);
        browser.setValue('input[id="id_meetingname"]', aNewMeetingName);
        browser.click("#btnMeetingSeriesSave");     // try to save
        E2EGlobal.waitSomeTime(750); // give dialog animation time

        expect(E2EMeetingSeries.getMeetingSeriesId(aProjectName, aMeetingName)).not.to.be.ok;
        expect(E2EMeetingSeries.getMeetingSeriesId(aNewProjectName, aNewMeetingName)).to.be.ok;
    });

    it('can restore fields after close and re-open @watch', function () {
        E2EMeetingSeriesEditor.openMeetingSeriesEditor(aProjectName, aMeetingName);
        browser.setValue('input[id="id_meetingproject"]', aProjectName+" Changed!");
        browser.setValue('input[id="id_meetingname"]', aMeetingName + " Changed!");

        browser.click('button.close');
        E2EGlobal.waitSomeTime(); // give dialog animation time

        E2EMeetingSeriesEditor.openMeetingSeriesEditor(aProjectName, aMeetingName, true);
        expect(browser.getValue('input[id="id_meetingproject"]')).to.equal(aProjectName);
        expect(browser.getValue('input[id="id_meetingname"]')).to.equal(aMeetingName);

        browser.click('button.close');
        E2EGlobal.waitSomeTime(); // give dialog animation time
    });

    it('can restore fields after cancel and re-open', function () {
        E2EMeetingSeriesEditor.openMeetingSeriesEditor(aProjectName, aMeetingName);
        browser.setValue('input[id="id_meetingproject"]', aProjectName+" Changed!");
        browser.setValue('input[id="id_meetingname"]', aMeetingName + " Changed!");

        browser.click('#btnMeetinSeriesEditCancel');
        E2EGlobal.waitSomeTime(); // give dialog animation time

        E2EMeetingSeriesEditor.openMeetingSeriesEditor(aProjectName, aMeetingName, true);
        expect(browser.getValue('input[id="id_meetingproject"]')).to.equal(aProjectName);
        expect(browser.getValue('input[id="id_meetingname"]')).to.equal(aMeetingName);

        browser.click('#btnMeetinSeriesEditCancel');
        E2EGlobal.waitSomeTime(); // give dialog animation time
    });

});
<commit_msg>Removed @watch<commit_after>
import { E2EGlobal } from './helpers/E2EGlobal'
import { E2EApp } from './helpers/E2EApp'
import { E2EMeetingSeries } from './helpers/E2EMeetingSeries'
import { E2EMeetingSeriesEditor } from './helpers/E2EMeetingSeriesEditor'
import { E2EMinutes } from './helpers/E2EMinutes'

describe('MeetingSeries Editor', function () {
    const aProjectName = "E2E MeetingSeries Editor";
    let aMeetingCounter = 0;
    let aMeetingNameBase = "Meeting Name #";
    let aMeetingName;

    beforeEach("goto start page and make sure test user is logged in", function () {
        E2EApp.gotoStartPage();
        expect(browser.getTitle()).to.equal('4minitz!');
        expect (E2EApp.isLoggedIn()).to.be.true;

        aMeetingCounter++;
        aMeetingName = aMeetingNameBase + aMeetingCounter;
        E2EMeetingSeries.createMeetingSeries(aProjectName, aMeetingName);
    });

    it('can open and close meeting series editor without changing data', function () {
        E2EMeetingSeriesEditor.openMeetingSeriesEditor(aProjectName, aMeetingName);
        // Now dialog should be there
        expect(browser.isVisible('#btnMeetingSeriesSave')).to.be.true;
        browser.click('button.close');
        E2EGlobal.waitSomeTime(); // give dialog animation time
        // Now dialog should be gone
        expect(browser.isVisible('#btnMeetingSeriesSave')).to.be.false;
        expect(E2EMeetingSeries.getMeetingSeriesId(aProjectName, aMeetingName)).not.to.be.false;
    });

    it('can open and cancel meeting series editor without changing data', function () {
        E2EMeetingSeriesEditor.openMeetingSeriesEditor(aProjectName, aMeetingName);
        // Now dialog should be there
        expect(browser.isVisible('#btnMeetinSeriesEditCancel')).to.be.true;
        browser.click('#btnMeetinSeriesEditCancel');
        E2EGlobal.waitSomeTime(); // give dialog animation time
        // Now dialog should be gone
        expect(browser.isVisible('#btnMeetinSeriesEditCancel')).to.be.false;
        expect(E2EMeetingSeries.getMeetingSeriesId(aProjectName, aMeetingName)).not.to.be.false;
    });

    it('can delete an empty meeting series', function () {
        let countAfterCreate = E2EMeetingSeries.countMeetingSeries();
        expect(E2EMeetingSeries.getMeetingSeriesId(aProjectName, aMeetingName)).to.be.ok;
        E2EMeetingSeriesEditor.openMeetingSeriesEditor(aProjectName, aMeetingName);

        browser.click("#deleteMeetingSeries");
        E2EApp.confirmationDialogAnswer(true);

        expect(E2EMeetingSeries.countMeetingSeries()).to.equal(countAfterCreate -1);
        expect(E2EMeetingSeries.getMeetingSeriesId(aProjectName, aMeetingName)).not.to.be.ok;
    });

    it('can cancel delete of meeting series', function () {
        let countAfterCreate = E2EMeetingSeries.countMeetingSeries();
        expect(E2EMeetingSeries.getMeetingSeriesId(aProjectName, aMeetingName)).to.be.ok;
        E2EMeetingSeriesEditor.openMeetingSeriesEditor(aProjectName, aMeetingName);

        browser.click("#deleteMeetingSeries");
        E2EApp.confirmationDialogAnswer(false);

        expect(E2EMeetingSeries.countMeetingSeries()).to.equal(countAfterCreate);
        expect(E2EMeetingSeries.getMeetingSeriesId(aProjectName, aMeetingName)).to.be.ok;
    });

    it('can clean up child minutes on deleting meeting series', function () {
        let aMeetingName = "Meeting Name (with Minute)";
        let countDBMeetingSeriesBefore = server.call('e2e.countMeetingSeriesInMongDB');
        let countDBMinutesBefore = server.call('e2e.countMinutesInMongoDB');
        E2EMeetingSeries.createMeetingSeries(aProjectName, aMeetingName);
        E2EMinutes.addMinutesToMeetingSeries(aProjectName, aMeetingName);
        E2EMinutes.finalizeCurrentMinutes();
        E2EMeetingSeries.gotoMeetingSeries(aProjectName, aMeetingName);

        // One more Meeting series and one more minutes
        expect(server.call('e2e.countMeetingSeriesInMongDB')).to.equal(countDBMeetingSeriesBefore +1);
        expect(server.call('e2e.countMinutesInMongoDB')).to.equal(countDBMinutesBefore +1);

        // Now delete meeting series with attached Minutes
        E2EMeetingSeriesEditor.openMeetingSeriesEditor(aProjectName, aMeetingName);
        browser.click("#deleteMeetingSeries");
        E2EApp.confirmationDialogAnswer(true);

        // Meeting series and attached minutes should be gone
        expect(server.call('e2e.countMeetingSeriesInMongDB')).to.equal(countDBMeetingSeriesBefore);
        expect(server.call('e2e.countMinutesInMongoDB')).to.equal(countDBMinutesBefore);
        expect(E2EMeetingSeries.getMeetingSeriesId(aProjectName, aMeetingName)).not.to.be.ok;
    });

    it('can not save meeting series without project or name', function () {
        E2EMeetingSeriesEditor.openMeetingSeriesEditor(aProjectName, aMeetingName);
        browser.setValue('input[id="id_meetingproject"]', "");  // empty input
        browser.setValue('input[id="id_meetingname"]', "");     // empty input
        browser.click("#btnMeetingSeriesSave");     // try to save
        expect(browser.isVisible("#btnMeetingSeriesSave")).to.be.true;  // dialog still open!

        browser.setValue('input[id="id_meetingproject"]', "XXX");
        browser.setValue('input[id="id_meetingname"]', "");     // empty input
        browser.click("#btnMeetingSeriesSave");     // try to save
        expect(browser.isVisible("#btnMeetingSeriesSave")).to.be.true;  // dialog still open!

        browser.setValue('input[id="id_meetingproject"]', "");  // empty input
        browser.setValue('input[id="id_meetingname"]', "XXX");
        browser.click("#btnMeetingSeriesSave");     // try to save
        expect(browser.isVisible("#btnMeetingSeriesSave")).to.be.true;  // dialog still open!

        browser.click('#btnMeetinSeriesEditCancel');
        E2EGlobal.waitSomeTime(750); // give dialog animation time
        expect(E2EMeetingSeries.getMeetingSeriesId(aProjectName, aMeetingName)).to.be.ok;  // prj/name should be unchanged
    });

    it('can save meeting series with new project name and meeting name', function () {
        E2EMeetingSeriesEditor.openMeetingSeriesEditor(aProjectName, aMeetingName);
        let aNewProjectName = "E2E New Project";
        let aNewMeetingName = "New Meeting Name";
        browser.setValue('input[id="id_meetingproject"]', aNewProjectName);
        browser.setValue('input[id="id_meetingname"]', aNewMeetingName);
        browser.click("#btnMeetingSeriesSave");     // try to save
        E2EGlobal.waitSomeTime(750); // give dialog animation time

        expect(E2EMeetingSeries.getMeetingSeriesId(aProjectName, aMeetingName)).not.to.be.ok;
        expect(E2EMeetingSeries.getMeetingSeriesId(aNewProjectName, aNewMeetingName)).to.be.ok;
    });

    it('can restore fields after close and re-open', function () {
        E2EMeetingSeriesEditor.openMeetingSeriesEditor(aProjectName, aMeetingName);
        browser.setValue('input[id="id_meetingproject"]', aProjectName+" Changed!");
        browser.setValue('input[id="id_meetingname"]', aMeetingName + " Changed!");

        browser.click('button.close');
        E2EGlobal.waitSomeTime(); // give dialog animation time

        E2EMeetingSeriesEditor.openMeetingSeriesEditor(aProjectName, aMeetingName, true);
        expect(browser.getValue('input[id="id_meetingproject"]')).to.equal(aProjectName);
        expect(browser.getValue('input[id="id_meetingname"]')).to.equal(aMeetingName);

        browser.click('button.close');
        E2EGlobal.waitSomeTime(); // give dialog animation time
    });

    it('can restore fields after cancel and re-open', function () {
        E2EMeetingSeriesEditor.openMeetingSeriesEditor(aProjectName, aMeetingName);
        browser.setValue('input[id="id_meetingproject"]', aProjectName+" Changed!");
        browser.setValue('input[id="id_meetingname"]', aMeetingName + " Changed!");

        browser.click('#btnMeetinSeriesEditCancel');
        E2EGlobal.waitSomeTime(); // give dialog animation time

        E2EMeetingSeriesEditor.openMeetingSeriesEditor(aProjectName, aMeetingName, true);
        expect(browser.getValue('input[id="id_meetingproject"]')).to.equal(aProjectName);
        expect(browser.getValue('input[id="id_meetingname"]')).to.equal(aMeetingName);

        browser.click('#btnMeetinSeriesEditCancel');
        E2EGlobal.waitSomeTime(); // give dialog animation time
    });

});
<|endoftext|>


<commit_before>var $ = require('jquery'),
    Overlay = require('overlay'),

    ua = (window.navigator.userAgent || '').toLowerCase(),
    isIE6 = ua.indexOf('msie 6') !== -1,

    zIndex = [],

    body = $(document.body),
    doc = $(document);

// Mask
// ----------
// 全屏遮罩层组件

var Mask = Overlay.extend({

    attrs: {
        width: isIE6 ? doc.outerWidth(true) : '100%',
        height: isIE6 ? doc.outerHeight(true) : '100%',

        className: 'ui-mask',
        opacity: 0.2,
        backgroundColor: '#000',
        style: {
            position: isIE6 ? 'absolute' : 'fixed',
            top: 0,
            left: 0
        },

        align: {
            // undefined 表示相对于当前可视范围定位
            baseElement: isIE6 ? body : undefined
        }
    },

    show: function () {
        if (isIE6) {
            this.set('width', doc.outerWidth(true));
            this.set('height', doc.outerHeight(true));
        }
        $('body').css({
            overflow: 'hidden'
        });
        return Mask.superclass.show.call(this);
    },

    setup: function () {
        // 加载 iframe 遮罩层并与 overlay 保持同步
        this._setupShim();
        this.before('show', function () {
            zIndex.push(this.get('zIndex'));
        });
    },
    hide: function () {
        zIndex.pop();
        if (zIndex.length > 0) {
            this.set('zIndex', zIndex[zIndex.length - 1]);
            return this;
        } else {
            $('body').css({
                overflow: ''
            });
            return Mask.superclass.hide.call(this);
        }
    },
    _onRenderBackgroundColor: function (val) {
        this.element.css('backgroundColor', val);
    },

    _onRenderOpacity: function (val) {
        this.element.css('opacity', val);
    }
});

// 单例
module.exports = new Mask();

<commit_msg>overlay -> arale-overlay<commit_after>var $ = require('jquery'),
    Overlay = require('arale-overlay'),

    ua = (window.navigator.userAgent || '').toLowerCase(),
    isIE6 = ua.indexOf('msie 6') !== -1,

    zIndex = [],

    body = $(document.body),
    doc = $(document);

// Mask
// ----------
// 全屏遮罩层组件

var Mask = Overlay.extend({

    attrs: {
        width: isIE6 ? doc.outerWidth(true) : '100%',
        height: isIE6 ? doc.outerHeight(true) : '100%',

        className: 'ui-mask',
        opacity: 0.2,
        backgroundColor: '#000',
        style: {
            position: isIE6 ? 'absolute' : 'fixed',
            top: 0,
            left: 0
        },

        align: {
            // undefined 表示相对于当前可视范围定位
            baseElement: isIE6 ? body : undefined
        }
    },

    show: function () {
        if (isIE6) {
            this.set('width', doc.outerWidth(true));
            this.set('height', doc.outerHeight(true));
        }
        $('body').css({
            overflow: 'hidden'
        });
        return Mask.superclass.show.call(this);
    },

    setup: function () {
        // 加载 iframe 遮罩层并与 overlay 保持同步
        this._setupShim();
        this.before('show', function () {
            zIndex.push(this.get('zIndex'));
        });
    },
    hide: function () {
        zIndex.pop();
        if (zIndex.length > 0) {
            this.set('zIndex', zIndex[zIndex.length - 1]);
            return this;
        } else {
            $('body').css({
                overflow: ''
            });
            return Mask.superclass.hide.call(this);
        }
    },
    _onRenderBackgroundColor: function (val) {
        this.element.css('backgroundColor', val);
    },

    _onRenderOpacity: function (val) {
        this.element.css('opacity', val);
    }
});

// 单例
module.exports = new Mask();

<|endoftext|>


<commit_before>describe('Volumes', function () {

  beforeEach(function () {
    cy.configureCluster({
      mesos: '1-task-with-volumes',
      nodeHealth: true
    });
  });

  context('Volumes Table', function () {

    beforeEach(function () {
      cy.visitUrl({url: '/services/%2Fsleep/'});
      cy.get('.page-content .tabs').contains('Volumes').click();
    });

    it('shows the correct number of volumes in the table', function () {
      cy.get('.table tbody tr').should(function ($rows) {
          // 3 rows of volumes + 2 rows for VirtualList = 5 rows total.
          expect($rows.length).to.equal(5);
        });
    });

    it('renders the correct IDs in the table', function () {
      cy.get('.table tbody tr').should(function ($rows) {
          var children = $rows[1].children;
          expect(children[0].textContent).to.equal('foo-bar#data-1#624f5b52-2e5e-11e6-8e49-a6a5a4687c4d');
          expect(children[1].textContent).to.equal('10.0.1.117');
          expect(children[2].textContent).to.equal('Persistent');
          expect(children[3].textContent).to.equal('data-1');
          expect(children[4].textContent).to.equal('100');
          expect(children[5].textContent).to.equal('RW');
          expect(children[6].textContent).to.equal('Attached');
        });
    });

  });

  context('Volume Details', function () {

    beforeEach(function () {
      cy.visitUrl({url: '/services/%2Fsleep/'});
      cy.get('.page-content .tabs').contains('Volumes').click();
      cy.get('.table tbody tr a').contains('foo-bar#data-1#624f5b52-2e5e-11e6-8e49-a6a5a4687c4d').click();
    });

    it('routes to the volume details by id', function () {
      cy.hash().should('match', new RegExp(encodeURIComponent('foo-bar#data-1#624f5b52-2e5e-11e6-8e49-a6a5a4687c4d')));
    });

    it('displays the correct status in the header', function () {
      cy.get('.page-header-container-left .emphasize').should('contain', 'Attached');
    });

    it('displays the details of the volume', function () {
      cy.get('.page-content dl.flex-box').should(function ($descriptionListEls) {
        expect($descriptionListEls[0].children[1].textContent).to.equal('data-1');
        expect($descriptionListEls[1].children[1].textContent).to.equal('RW');
        expect($descriptionListEls[2].children[1].textContent).to.equal('100');
        expect($descriptionListEls[3].children[1].textContent).to.equal('/sleep');
        expect($descriptionListEls[4].children[1].textContent).to.equal('10.0.1.117');
      });
    });

  });

});

<commit_msg>Fix PageHeader class<commit_after>describe('Volumes', function () {

  beforeEach(function () {
    cy.configureCluster({
      mesos: '1-task-with-volumes',
      nodeHealth: true
    });
  });

  context('Volumes Table', function () {

    beforeEach(function () {
      cy.visitUrl({url: '/services/%2Fsleep/'});
      cy.get('.page-content .tabs').contains('Volumes').click();
    });

    it('shows the correct number of volumes in the table', function () {
      cy.get('.table tbody tr').should(function ($rows) {
          // 3 rows of volumes + 2 rows for VirtualList = 5 rows total.
          expect($rows.length).to.equal(5);
        });
    });

    it('renders the correct IDs in the table', function () {
      cy.get('.table tbody tr').should(function ($rows) {
          var children = $rows[1].children;
          expect(children[0].textContent).to.equal('foo-bar#data-1#624f5b52-2e5e-11e6-8e49-a6a5a4687c4d');
          expect(children[1].textContent).to.equal('10.0.1.117');
          expect(children[2].textContent).to.equal('Persistent');
          expect(children[3].textContent).to.equal('data-1');
          expect(children[4].textContent).to.equal('100');
          expect(children[5].textContent).to.equal('RW');
          expect(children[6].textContent).to.equal('Attached');
        });
    });

  });

  context('Volume Details', function () {

    beforeEach(function () {
      cy.visitUrl({url: '/services/%2Fsleep/'});
      cy.get('.page-content .tabs').contains('Volumes').click();
      cy.get('.table tbody tr a').contains('foo-bar#data-1#624f5b52-2e5e-11e6-8e49-a6a5a4687c4d').click();
    });

    it('routes to the volume details by id', function () {
      cy.hash().should('match', new RegExp(encodeURIComponent('foo-bar#data-1#624f5b52-2e5e-11e6-8e49-a6a5a4687c4d')));
    });

    it('displays the correct status in the header', function () {
      cy.get('.page-header-heading .emphasize').should('contain', 'Attached');
    });

    it('displays the details of the volume', function () {
      cy.get('.page-content dl.flex-box').should(function ($descriptionListEls) {
        expect($descriptionListEls[0].children[1].textContent).to.equal('data-1');
        expect($descriptionListEls[1].children[1].textContent).to.equal('RW');
        expect($descriptionListEls[2].children[1].textContent).to.equal('100');
        expect($descriptionListEls[3].children[1].textContent).to.equal('/sleep');
        expect($descriptionListEls[4].children[1].textContent).to.equal('10.0.1.117');
      });
    });

  });

});

<|endoftext|>


<commit_before>/**
 * Created by Kylart on 18/03/2017.
 */

const self = this

const path = require('path')
const electron = require('electron')
const app = require('electron').app
const url = require('url')
const BrowserWindow = electron.BrowserWindow

let preferencesWindow

let template = [
  {
    label: 'Edit',
    submenu: [
      {
        role: 'copy'
      },
      {
        role: 'paste'
      },
      {
        role: 'delete'
      }
    ]
  },
  {
    label: 'View',
    submenu: [
      {
        role: 'reload'
      },
      {
        role: 'forcereload'
      },
      {
        type: 'separator'
      },
      {
        role: 'resetzoom'
      },
      {
        role: 'zoomin'
      },
      {
        role: 'zoomout'
      },
      {
        type: 'separator'
      },
      {
        role: 'togglefullscreen'
      },
      {
        type: 'separator'
      },
      {
        label: 'Developpers',
        submenu: [
          {
            role: 'toggledevtools'
          }
        ]
      }
    ]
  },
  {
    role: 'window',
    submenu: [
      {
        role: 'minimize'
      },
      {
        role: 'close'
      }
    ]
  },
  {
    role: 'help',
    submenu: [
      {
        label: 'Learn More',
        click () { require('electron').shell.openExternal('https://github.com/Kylart/KawAnime') }
      }
    ]
  }
]

if (process.platform === 'darwin') {
  template.unshift({
    label: app.getName(),
    submenu: [
      {
        role: 'about'
      },
      {
        type: 'separator'
      },
      {
        label: 'Preferences',
        accelerator: 'Cmd+,',
        click: function () {
          self.openPreferences()
        }
      },
      {
        type: 'separator'
      },
      {
        role: 'services',
        submenu: []
      },
      {
        type: 'separator'
      },
      {
        role: 'hide'
      },
      {
        role: 'hideothers'
      },
      {
        role: 'unhide'
      },
      {
        type: 'separator'
      },
      {
        role: 'quit'
      }
    ]
  })
  // Edit menu.
  template[1].submenu.push(
      {
        type: 'separator'
      },
      {
        label: 'Speech',
        submenu: [
          {
            role: 'startspeaking'
          },
          {
            role: 'stopspeaking'
          }
        ]
      }
  )
  // Window menu.
  template[3].submenu = [
    {
      label: 'Close',
      accelerator: 'CmdOrCtrl+W',
      role: 'close'
    },
    {
      label: 'Minimize',
      accelerator: 'CmdOrCtrl+M',
      role: 'minimize'
    },
    {
      label: 'Zoom',
      role: 'zoom'
    },
    {
      type: 'separator'
    },
    {
      label: 'Bring All to Front',
      role: 'front'
    }
  ]
}

exports.template = template

// Preferences window
exports.openPreferences = () => {
  // Create the browser window.
  preferencesWindow = new BrowserWindow({
    x: 50,
    y: 50,
    width: 800,
    height: 500,
    minimizable: false,
    maximizable: false,
    frame: 'none',
    titleBarStyle: 'hidden'
  })

  // and load the index.html of the src.
  preferencesWindow.loadURL(url.format({
    pathname: path.join(__dirname, 'preferences', 'index.html'),
    protocol: 'file:',
    slashes: true
  }))

  preferencesWindow.once('ready-to-show', () => {
    preferencesWindow.show()
  })

  // Emitted when the window is closed.
  preferencesWindow.on('closed', function () {
    // Dereference the window object, usually you would store windows
    // in an array if your src supports multi windows, this is the time
    // when you should delete the corresponding element.
    preferencesWindow = null
  })
}<commit_msg>Oups, forgot preferences window for windows and Linux..<commit_after>/**
 * Created by Kylart on 18/03/2017.
 */

const self = this

const path = require('path')
const electron = require('electron')
const app = require('electron').app
const url = require('url')
const BrowserWindow = electron.BrowserWindow

let preferencesWindow

let template = [
  {
    label: 'Edit',
    submenu: [
      {
        role: 'copy'
      },
      {
        role: 'paste'
      },
      {
        role: 'delete'
      },
      {
        type: 'separator'
      },
      {
        label: 'preferences',
        accelerator: 'Ctrl+,',
        click: function () {
          self.openPreferences()
        }
      }
    ]
  },
  {
    label: 'View',
    submenu: [
      {
        role: 'reload'
      },
      {
        role: 'forcereload'
      },
      {
        type: 'separator'
      },
      {
        role: 'resetzoom'
      },
      {
        role: 'zoomin'
      },
      {
        role: 'zoomout'
      },
      {
        type: 'separator'
      },
      {
        role: 'togglefullscreen'
      },
      {
        type: 'separator'
      },
      {
        label: 'Developpers',
        submenu: [
          {
            role: 'toggledevtools'
          }
        ]
      }
    ]
  },
  {
    role: 'window',
    submenu: [
      {
        role: 'minimize'
      },
      {
        role: 'close'
      }
    ]
  },
  {
    role: 'help',
    submenu: [
      {
        label: 'Learn More',
        click () { require('electron').shell.openExternal('https://github.com/Kylart/KawAnime') }
      }
    ]
  }
]

if (process.platform === 'darwin') {
  template.unshift({
    label: app.getName(),
    submenu: [
      {
        role: 'about'
      },
      {
        type: 'separator'
      },
      {
        label: 'Preferences',
        accelerator: 'Cmd+,',
        click: function () {
          self.openPreferences()
        }
      },
      {
        type: 'separator'
      },
      {
        role: 'services',
        submenu: []
      },
      {
        type: 'separator'
      },
      {
        role: 'hide'
      },
      {
        role: 'hideothers'
      },
      {
        role: 'unhide'
      },
      {
        type: 'separator'
      },
      {
        role: 'quit'
      }
    ]
  })
  // Edit menu.
  template[1].submenu.push(
      {
        type: 'separator'
      },
      {
        label: 'Speech',
        submenu: [
          {
            role: 'startspeaking'
          },
          {
            role: 'stopspeaking'
          }
        ]
      }
  )
  // Window menu.
  template[3].submenu = [
    {
      label: 'Close',
      accelerator: 'CmdOrCtrl+W',
      role: 'close'
    },
    {
      label: 'Minimize',
      accelerator: 'CmdOrCtrl+M',
      role: 'minimize'
    },
    {
      label: 'Zoom',
      role: 'zoom'
    },
    {
      type: 'separator'
    },
    {
      label: 'Bring All to Front',
      role: 'front'
    }
  ]
}

exports.template = template

// Preferences window
exports.openPreferences = () => {
  // Create the browser window.
  preferencesWindow = new BrowserWindow({
    x: 50,
    y: 50,
    width: 800,
    height: 500,
    minimizable: false,
    maximizable: false,
    frame: 'none',
    titleBarStyle: 'hidden'
  })

  // and load the index.html of the src.
  preferencesWindow.loadURL(url.format({
    pathname: path.join(__dirname, 'preferences', 'index.html'),
    protocol: 'file:',
    slashes: true
  }))

  preferencesWindow.once('ready-to-show', () => {
    preferencesWindow.show()
  })

  // Emitted when the window is closed.
  preferencesWindow.on('closed', function () {
    // Dereference the window object, usually you would store windows
    // in an array if your src supports multi windows, this is the time
    // when you should delete the corresponding element.
    preferencesWindow = null
  })
}<|endoftext|>


<commit_before>(function () {

    // helpers
    var toString = Object.prototype.toString;

    // test if object
    var isObject = function (arg) {
        return toString.call(arg) === '[object Object]';
    };

    var finance = function (arg1) { // core constructor
        // ensure to use the `new` operator
        if (!(this instanceof finance)) {
            return new finance(arg1);
        }

        // if first argument is an array
        if (isObject(arg1)) {
            this._symbol = arg1.symbol;
            this._fromDate = arg1.fromDate;
            this._toDate = arg1.toDate;
            this._data = arg1.data !== undefined ? arg1.data : [];
            this._volume = arg1.volume !== undefined ? arg1.volume : [];
            // handle case when finance object is passed to finance
        } else if (arg1 instanceof finance) {
            // duplicate the object and pass it back
            return finance({
                symbol: this._symbol,
                fromDate: this._fromDate,
                toDate: this._toDate,
                price: this._data,
                volume: this._volume
            });
            // unexpected argument value, return empty finance object
        } else {
            this._symbol = '^VIX';
            this._fromDate = moment("1960-09-11");
            this._toDate = moment("2014-11-09");
            this._data = [];
            this._volume = [];
        }
        return this;
    };

    function downloadData(symbol, fromDate, toDate) {

        function parseYear(date) {
            return date.format('YYYY');
        }
        function parseMonth(date) {
            return parseInt(date.format('MM')) - 1;
        }
        function parseDay(date) {
            return date.format('DD');
        }

        log.debug("Getting historical prices from yahoo finance for symbol " + symbol + " between date " + fromDate.format("YYYY-MM-DD") + " to " + toDate.format("YYYY-MM-DD"));
        var columns = "*";
        var url = "http://ichart.finance.yahoo.com/table.csv?" + $.param({
            s: symbol,
            a: parseMonth(fromDate),
            b: parseDay(fromDate),
            c: parseYear(fromDate),
            d: parseMonth(toDate),
            e: parseDay(toDate),
            f: parseYear(toDate),
            g: "d",
            ignore: ".cvs"
        });
        var columnAliases = "date,open,high,low,close,volume,adjclose";
        var query = "select " + columns + " from csv where url='" + url + "' and columns='" + columnAliases + "'";

        var returnData;
        var jqXHR = $.ajax("http://query.yahooapis.com/v1/public/yql", {
            data: {
                q: query,
                ignore: ".cvs",
                format: "json",
                diagnostics: true
            },
            async: false,
            dataType: "json",
            crossDomain: true
        }).done(function(data) {
            if (data.query.results !== undefined && data.query.results.row !== undefined) {
                if (data.query.results.row.length > 0) {
                    data.query.results.row.shift(); // remove descriptions
                    var from = data.query.results.row[data.query.results.row.length - 1];
                    var to = data.query.results.row[0];
                    log.debug("Historical prices between date " + from.date + " to " + to.date + " (" + from.close + " to " + to.close + ") received");
                }
            }
            log.debug("data.query.results.row", data.query.results.row);
            returnData = data.query.results.row;

            if (data.query.diagnostics.csv !== undefined) {
                log.warn("diagnostics.cvs = " + data.query.diagnostics.csv);
            }
            if (data.query.diagnostics.warning !== undefined) {
                log.warn("diagnostics.warning = " + data.query.diagnostics.warning);
                if (data.query.diagnostics.warning === "You have reached the maximum number of items which can be returned in a request") {
                    var recursiveToDate = moment(from.date).subtract('days', 1);
                    Array.prototype.push.apply(returnData, downloadData(symbol, fromDate, recursiveToDate));
                }
            }
        }).fail(function() {
            alert( "Error downloading data" );
        }).always(function() {

        });

        return returnData;
    }

    // create `fn` alias to `prototype` property
    finance.fn = finance.prototype = {};

    /**
     * Get the symbol price
     *
     * @return     {Array}    the Symbol Price
     */
    finance.fn.price = function () {
        var start = moment().valueOf();
        this._data = downloadData(this._symbol, this._fromDate, this._toDate);
        log.info(JSON.stringify(this._data));
        var stop = moment().valueOf();
        var executionTime = stop - start;
        log.debug("Downloading data took " + executionTime + " milliseconds");
        return this._data;
    };

    /**
     * Get the Symbol Volume
     *
     * @return     {Array}    the Symbol Volume
     */
    finance.fn.volume = function () {
        return this._volume;
    };

    // expose the library
    window.finance = finance;
})();

var log = log4javascript.getDefaultLogger();
var consoleAppender = new log4javascript.BrowserConsoleAppender()
log.removeAllAppenders();
log.addAppender(consoleAppender);
consoleAppender.setThreshold(log4javascript.Level.DEBUG);
log.setLevel(log4javascript.Level.TRACE);
log.trace("Document Ready");

log.info(finance().price());<commit_msg>Cleaned up code and some refactoring for finance.js
<commit_after>(function () {

    // helpers
    var toString = Object.prototype.toString;

    // test if object
    var isObject = function (arg) {
        return toString.call(arg) === '[object Object]';
    };

    var finance = function (arg1) { // core constructor
        // ensure to use the `new` operator
        if (!(this instanceof finance)) {
            return new finance(arg1);
        }

        // if first argument is an array
        if (isObject(arg1) && arg1.symbol !== undefined) {
            this._symbol = arg1.symbol;
            this._data = arg1.data !== undefined ? arg1.data : [];
        // unexpected argument value, return empty finance object
        } else {
            throw "First argument must be an object containing a symbol";
        }
        return this;
    };

    function downloadData(symbol, fromDate, toDate) {

        function parseYear(date) {
            return date.format('YYYY');
        }
        function parseMonth(date) {
            return parseInt(date.format('MM')) - 1;
        }
        function parseDay(date) {
            return date.format('DD');
        }

        log.debug("Getting historical prices from yahoo finance for symbol " + symbol + " between date " + fromDate.format("YYYY-MM-DD") + " to " + toDate.format("YYYY-MM-DD"));
        var columns = "*";
        var url = "http://ichart.finance.yahoo.com/table.csv?" + $.param({
            s: symbol,
            a: parseMonth(fromDate),
            b: parseDay(fromDate),
            c: parseYear(fromDate),
            d: parseMonth(toDate),
            e: parseDay(toDate),
            f: parseYear(toDate),
            g: "d",
            ignore: ".cvs"
        });
        var columnAliases = "date,open,high,low,close,volume,adjclose";
        var query = "select " + columns + " from csv where url='" + url + "' and columns='" + columnAliases + "'";

        var returnData;
        var jqXHR = $.ajax("http://query.yahooapis.com/v1/public/yql", {
            data: {
                q: query,
                ignore: ".cvs",
                format: "json",
                diagnostics: true
            },
            async: false,
            dataType: "json",
            crossDomain: true
        }).done(function(data) {
            if (data.query.results !== undefined && data.query.results.row !== undefined) {
                if (data.query.results.row.length > 0) {
                    data.query.results.row.shift(); // remove descriptions
                    var from = data.query.results.row[data.query.results.row.length - 1];
                    var to = data.query.results.row[0];
                    log.debug("Historical prices between date " + from.date + " to " + to.date + " (" + from.close + " to " + to.close + ") received");
                }
            }
            log.debug("data.query.results.row", data.query.results.row);
            returnData = data.query.results.row;

            if (data.query.diagnostics.csv !== undefined) {
                log.warn("diagnostics.cvs = " + data.query.diagnostics.csv);
            }
            if (data.query.diagnostics.warning !== undefined) {
                if (data.query.diagnostics.warning === "You have reached the maximum number of items which can be returned in a request") {
                    log.debug("Was not able to receive all data in on call");
                    log.debug("Calling downloadData recursively to download the rest of the data");
                    var recursiveToDate = moment(from.date).subtract('days', 1);
                    Array.prototype.push.apply(returnData, downloadData(symbol, fromDate, recursiveToDate));
                } else {
                    log.warn("diagnostics.warning = " + data.query.diagnostics.warning);
                }
            }
        }).fail(function() {
            alert( "Error downloading data" );
        }).always(function() {

        });

        return returnData;
    }

    // create `fn` alias to `prototype` property
    finance.fn = finance.prototype = {};

    /**
     * Get the symbol price
     *
     * @return     {Array}    the Symbol Price
     */
    finance.fn.data = function () {
        var start = moment().valueOf();
        var fromDate = moment("1900-01-01");
        var toDate = moment();
        this._data = downloadData(this._symbol, fromDate, toDate);
        var stop = moment().valueOf();
        var executionTime = stop - start;
        log.debug("Downloading data took " + executionTime + " milliseconds");
        return this._data;
    };

    /**
     * Get the Symbol Volume
     *
     * @return     {Array}    the Symbol Volume
     */
    finance.fn.volume = function () {
        return this._volume;
    };

    // expose the library
    window.finance = finance;
})();

var log = log4javascript.getDefaultLogger();
var consoleAppender = new log4javascript.BrowserConsoleAppender()
log.removeAllAppenders();
log.addAppender(consoleAppender);
consoleAppender.setThreshold(log4javascript.Level.DEBUG);
log.setLevel(log4javascript.Level.TRACE);
log.trace("Document Ready");

log.info(finance({symbol: "^VIX"}).data());<|endoftext|>