PageRenderTime 49ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/JSLib/tests/common/TestSynchronizerClient.js

#
JavaScript | 218 lines | 152 code | 36 blank | 30 comment | 23 complexity | 007990b2813b8429dfa00512eb3e948a MD5 | raw file
  1. // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
  2. // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
  3. // files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
  4. // modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
  5. // Software is furnished to do so, subject to the following conditions:
  6. //
  7. // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
  8. //
  9. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  10. // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  11. // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  12. // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  13. // TestSynchronizer Client
  14. // Use to log assert pass/fails and notify mstest a test has completed execution
  15. (function (window, undefined) {
  16. var testRunId = "";
  17. var serviceRoot = "./common/TestLogger.svc/";
  18. var recording = null;
  19. var recordingLength = 0;
  20. var maxStringLength = 8192;
  21. var maxPostLength = 2097152;
  22. var callTestSynchronizer = function (methodName, parameterUrl) {
  23. /// <summary>Invokes a function on the test synchronizer.</summary>
  24. /// <param name="partialUrl" type="String" optional="true">URL to work with.</param>
  25. /// <returns type="String">A response from the server, possibly null.</returns>
  26. /// <remarks>
  27. /// If the recording variable is assigned, then the call is logged
  28. /// but nothing is invoked.
  29. /// </remarks>
  30. var partialUrl;
  31. if (testRunId) {
  32. partialUrl = methodName + "?testRunId=" + testRunId + "&" + parameterUrl;
  33. }
  34. else {
  35. partialUrl = methodName + "?" + parameterUrl;
  36. }
  37. var url = serviceRoot + partialUrl;
  38. if (recording) {
  39. if (url.length > maxStringLength) {
  40. url = url.substr(0, maxStringLength);
  41. }
  42. recordingLength += url.length;
  43. if (recordingLength > maxPostLength) {
  44. submitRecording();
  45. recording = [];
  46. recordingLength = url.length;
  47. }
  48. recording.push(url);
  49. return null;
  50. }
  51. var xhr;
  52. if (window.XMLHttpRequest) {
  53. xhr = new window.XMLHttpRequest();
  54. } else {
  55. xhr = new ActiveXObject("Msxml2.XMLHTTP.6.0");
  56. }
  57. xhr.open("GET", url, false);
  58. xhr.send();
  59. return xhr.responseText;
  60. };
  61. var getLogPrefix = function (result) {
  62. /// <summary>Returns the log prefix for a given result</summary>
  63. /// <param name="result" type="Boolean">Whether the result is pass or fail. If null, the log line is assumed to be diagnostic</param>
  64. return "[" + getShortDate() + "] " + (result === true ? "[PASS] " : (result === false ? "[FAIL] " : ""));
  65. };
  66. var getShortDate = function () {
  67. /// <summary>Returns the current date and time formatted as "yyyy-mm-dd hh:mm:ss.nnn".</summary>
  68. var padToLength = function (number, length) {
  69. var result = number + "";
  70. var lengthDiff = length - result.length;
  71. for (var i = 0; i < lengthDiff; i++) {
  72. result = "0" + result;
  73. }
  74. return result;
  75. }
  76. var date = new Date();
  77. var day = padToLength(date.getDate(), 2);
  78. var month = padToLength(date.getMonth() + 1, 2);
  79. var year = date.getFullYear();
  80. var hours = padToLength(date.getHours(), 2);
  81. var minutes = padToLength(date.getMinutes(), 2);
  82. var seconds = padToLength(date.getSeconds(), 2);
  83. var milliseconds = padToLength(date.getMilliseconds(), 3);
  84. return year + "-" + month + "-" + day + " " + hours + ":" + minutes + ":" + seconds + "." + milliseconds;
  85. };
  86. var submitRecording = function () {
  87. var body = { urls: recording };
  88. postToUrl("LogBatch", body);
  89. };
  90. var postToUrl = function (methodName, body) {
  91. /// <summary>POSTs body to the designated methodName.</summary>
  92. var xhr;
  93. if (window.XMLHttpRequest) {
  94. xhr = new window.XMLHttpRequest();
  95. } else {
  96. xhr = new ActiveXObject("Msxml2.XMLHTTP.6.0");
  97. }
  98. var url = serviceRoot + methodName;
  99. xhr.open("POST", url, false);
  100. xhr.setRequestHeader("Content-Type", "application/json");
  101. xhr.send(window.JSON.stringify(body));
  102. if (xhr.status < 200 || xhr.status > 299) {
  103. throw { message: "Unable to POST to url.\r\n" + xhr.responseText };
  104. }
  105. return xhr.responseText;
  106. }
  107. function LogAssert(result, message, name, expected, actual) {
  108. var parameterUrl = "pass=" + result + "&message=" + encodeURIComponent(message) + "&name=" + encodeURIComponent(name);
  109. if (!result) {
  110. parameterUrl += "&actual=" + encodeURIComponent(actual) + "&expected=" + encodeURIComponent(expected);
  111. }
  112. callTestSynchronizer("LogAssert", parameterUrl);
  113. }
  114. function LogTestStart(name) {
  115. callTestSynchronizer("LogTestStart", "name=" + encodeURIComponent(name) + "&startTime=" + encodeURIComponent(getShortDate()));
  116. }
  117. function LogTestDone(name, failures, total) {
  118. callTestSynchronizer("LogTestDone", "name=" + encodeURIComponent(name) + "&failures=" + failures + "&total=" + total + "&endTime=" + encodeURIComponent(getShortDate()));
  119. }
  120. function TestCompleted(failures, total) {
  121. return callTestSynchronizer("TestCompleted", "failures=" + failures + "&total=" + total);
  122. }
  123. var extractTestRunId = function () {
  124. /// <summary>Extracts the testRunId value from the window query string.</summary>
  125. /// <returns type="String">testRunId, possibly empty.</returns>
  126. var i, len;
  127. var uri = window.location.search;
  128. if (uri) {
  129. var parameters = uri.split("&");
  130. for (i = 0, len = parameters.length; i < len; i++) {
  131. var index = parameters[i].indexOf("testRunId=");
  132. if (index >= 0) {
  133. return parameters[i].substring(index + "testRunId=".length);
  134. }
  135. }
  136. }
  137. return "";
  138. };
  139. var init = function (qunit) {
  140. /// <summary>Initializes the test logger synchronizer.</summary>
  141. /// <param name="qunit">Unit testing to hook into.</param>
  142. /// <remarks>If there is no testRunId present, the QUnit functions are left as they are.</remarks>
  143. var logToConsole = function (context) {
  144. if (window.console && window.console.log) {
  145. window.console.log(context.result + ' :: ' + context.message);
  146. }
  147. };
  148. testRunId = extractTestRunId();
  149. if (!testRunId) {
  150. qunit.log = logToConsole;
  151. } else {
  152. recording = [];
  153. qunit.log = function (context) {
  154. logToConsole(context);
  155. var name = qunit.config.current.testName;
  156. if (!(context.actual && context.expected)) {
  157. context.actual = context.result;
  158. context.expected = true;
  159. }
  160. LogAssert(context.result, getLogPrefix(context.result) + context.message, name, window.JSON.stringify(context.expected), window.JSON.stringify(context.actual));
  161. };
  162. qunit.testStart = function (context) {
  163. LogTestStart(context.name);
  164. };
  165. qunit.testDone = function (context) {
  166. LogTestDone(context.name, context.failed, context.total);
  167. }
  168. qunit.done = function (context) {
  169. submitRecording();
  170. recording = null;
  171. var nextUrl = TestCompleted(context.failed, context.total);
  172. nextUrl = JSON.parse(nextUrl).d;
  173. if (nextUrl) {
  174. window.location.href = nextUrl;
  175. }
  176. }
  177. }
  178. };
  179. window.TestSynchronizer = {
  180. init: init
  181. };
  182. })(window);