diff --git a/build/repo.targets b/build/repo.targets
index 954b78e7b4ad..dbad646118b4 100644
--- a/build/repo.targets
+++ b/build/repo.targets
@@ -33,7 +33,7 @@
-
+
diff --git a/clients/ts/FunctionalTests/package-lock.json b/clients/ts/FunctionalTests/package-lock.json
index ed6372b19379..d0a0e4e235f2 100644
--- a/clients/ts/FunctionalTests/package-lock.json
+++ b/clients/ts/FunctionalTests/package-lock.json
@@ -4,12 +4,6 @@
"lockfileVersion": 1,
"requires": true,
"dependencies": {
- "@std/esm": {
- "version": "0.18.0",
- "resolved": "https://registry.npmjs.org/@std/esm/-/esm-0.18.0.tgz",
- "integrity": "sha512-oeHSSVp/WxC08ngpKgyYR4LcI0+EBwZiJcB58jvIqyJnOGxudSkxTgAQKsVfpNsMXfOoILgu9PWhuzIZ8GQEjw==",
- "dev": true
- },
"@types/debug": {
"version": "0.0.30",
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-0.0.30.tgz",
@@ -43,18 +37,21 @@
"color-convert": "1.9.1"
}
},
+ "argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "requires": {
+ "sprintf-js": "1.0.3"
+ }
+ },
"arrify": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
"integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
"dev": true
},
- "buffer-shims": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz",
- "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=",
- "dev": true
- },
"chalk": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
@@ -81,12 +78,6 @@
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true
},
- "core-util-is": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
- "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
- "dev": true
- },
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
@@ -102,12 +93,6 @@
"integrity": "sha512-QpVuMTEoJMF7cKzi6bvWhRulU1fZqZnvyVQgNhPaxxuTYwyjn/j1v9falseQ/uXWwPnO56RBfwtg4h/EQXmucA==",
"dev": true
},
- "duplexer": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
- "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=",
- "dev": true
- },
"es6-promise": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.2.tgz",
@@ -120,32 +105,17 @@
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
"dev": true
},
- "figures": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
- "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=",
- "dev": true,
- "requires": {
- "escape-string-regexp": "1.0.5",
- "object-assign": "4.1.1"
- }
+ "esprima": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz",
+ "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==",
+ "dev": true
},
- "has-ansi": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
- "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
- "dev": true,
- "requires": {
- "ansi-regex": "2.1.1"
- },
- "dependencies": {
- "ansi-regex": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
- "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
- "dev": true
- }
- }
+ "events-to-array": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/events-to-array/-/events-to-array-1.1.2.tgz",
+ "integrity": "sha1-LUH1Y+H+QA7Uli/hpNXGp1Od9/Y=",
+ "dev": true
},
"has-flag": {
"version": "2.0.0",
@@ -162,33 +132,16 @@
"parse-passwd": "1.0.0"
}
},
- "inherits": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
- "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
- "dev": true
- },
- "is-finite": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
- "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
+ "js-yaml": {
+ "version": "3.11.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.11.0.tgz",
+ "integrity": "sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw==",
"dev": true,
"requires": {
- "number-is-nan": "1.0.1"
+ "argparse": "1.0.10",
+ "esprima": "4.0.0"
}
},
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
- "dev": true
- },
- "lodash": {
- "version": "3.10.1",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
- "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=",
- "dev": true
- },
"make-error": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.3.tgz",
@@ -201,6 +154,16 @@
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true
},
+ "minipass": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.2.4.tgz",
+ "integrity": "sha512-hzXIWWet/BzWhYs2b+u7dRHlruXhwdgvlTMDKC6Cb1U7ps6Ac6yQlR39xsbjWJE377YTCtKwIXIpJ5oP+j5y8g==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "5.1.1",
+ "yallist": "3.0.2"
+ }
+ },
"mkdirp": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
@@ -224,79 +187,12 @@
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
"dev": true
},
- "number-is-nan": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
- "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
- "dev": true
- },
- "object-assign": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
- "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
- "dev": true
- },
- "parse-ms": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-1.0.1.tgz",
- "integrity": "sha1-VjRtR0nXjyNDDKDHE4UK75GqNh0=",
- "dev": true
- },
"parse-passwd": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
"integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
"dev": true
},
- "plur": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/plur/-/plur-1.0.0.tgz",
- "integrity": "sha1-24XGgU9eXlo7Se/CjWBP7GKXUVY=",
- "dev": true
- },
- "pretty-ms": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-2.1.0.tgz",
- "integrity": "sha1-QlfCVt8/sLRR1q/6qwIYhBJpgdw=",
- "dev": true,
- "requires": {
- "is-finite": "1.0.2",
- "parse-ms": "1.0.1",
- "plur": "1.0.0"
- }
- },
- "process-nextick-args": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
- "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
- "dev": true
- },
- "re-emitter": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/re-emitter/-/re-emitter-1.1.3.tgz",
- "integrity": "sha1-+p4xn/3u6zWycpbvDz03TawvUqc=",
- "dev": true
- },
- "readable-stream": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz",
- "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=",
- "dev": true,
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "string_decoder": "0.10.31",
- "util-deprecate": "1.0.2"
- }
- },
- "repeat-string": {
- "version": "1.6.1",
- "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
- "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
- "dev": true
- },
"safe-buffer": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
@@ -318,19 +214,10 @@
"source-map": "0.6.1"
}
},
- "split": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz",
- "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==",
- "dev": true,
- "requires": {
- "through": "2.3.8"
- }
- },
- "string_decoder": {
- "version": "0.10.31",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
- "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+ "sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
"dev": true
},
"strip-bom": {
@@ -354,179 +241,15 @@
"has-flag": "2.0.0"
}
},
- "tap-out": {
- "version": "1.4.2",
- "resolved": "https://registry.npmjs.org/tap-out/-/tap-out-1.4.2.tgz",
- "integrity": "sha1-yQfsG/lAURHQiCY+kvVgi4jLs3o=",
- "dev": true,
- "requires": {
- "re-emitter": "1.1.3",
- "readable-stream": "2.0.6",
- "split": "1.0.1",
- "trim": "0.0.1"
- }
- },
- "tap-spec": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/tap-spec/-/tap-spec-4.1.1.tgz",
- "integrity": "sha1-4unyb1IIIysfViKIyXYk1YqI8Fo=",
- "dev": true,
- "requires": {
- "chalk": "1.1.3",
- "duplexer": "0.1.1",
- "figures": "1.7.0",
- "lodash": "3.10.1",
- "pretty-ms": "2.1.0",
- "repeat-string": "1.6.1",
- "tap-out": "1.4.2",
- "through2": "2.0.3"
- },
- "dependencies": {
- "ansi-regex": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
- "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
- "dev": true
- },
- "ansi-styles": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
- "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
- "dev": true
- },
- "chalk": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
- "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
- "dev": true,
- "requires": {
- "ansi-styles": "2.2.1",
- "escape-string-regexp": "1.0.5",
- "has-ansi": "2.0.0",
- "strip-ansi": "3.0.1",
- "supports-color": "2.0.0"
- }
- },
- "process-nextick-args": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
- "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
- "dev": true
- },
- "readable-stream": {
- "version": "2.3.4",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.4.tgz",
- "integrity": "sha512-vuYxeWYM+fde14+rajzqgeohAI7YoJcHE7kXDAc4Nk0EbuKnJfqtY9YtRkLo/tqkuF7MsBQRhPnPeyjYITp3ZQ==",
- "dev": true,
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "2.0.0",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "dev": true,
- "requires": {
- "safe-buffer": "5.1.1"
- }
- },
- "strip-ansi": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
- "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
- "dev": true,
- "requires": {
- "ansi-regex": "2.1.1"
- }
- },
- "supports-color": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
- "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
- "dev": true
- },
- "through2": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz",
- "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=",
- "dev": true,
- "requires": {
- "readable-stream": "2.3.4",
- "xtend": "4.0.1"
- }
- },
- "xtend": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
- "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
- "dev": true
- }
- }
- },
- "tap-teamcity": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/tap-teamcity/-/tap-teamcity-3.0.2.tgz",
- "integrity": "sha512-FI26a4CGNx9LWx2vRh3fLNrel1GJm5smBVJl2tzabTwGrmX9d+KHWP2O9xdKgMtH5IOBpN6goy9Yh4P2NRaoQw==",
+ "tap-parser": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-7.0.0.tgz",
+ "integrity": "sha512-05G8/LrzqOOFvZhhAk32wsGiPZ1lfUrl+iV7+OkKgfofZxiceZWMHkKmow71YsyVQ8IvGBP2EjcIjE5gL4l5lA==",
"dev": true,
"requires": {
- "@std/esm": "0.18.0",
- "duplexer": "0.1.1",
- "tap-out": "2.0.0",
- "through2": "2.0.3"
- },
- "dependencies": {
- "readable-stream": {
- "version": "2.2.9",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz",
- "integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=",
- "dev": true,
- "requires": {
- "buffer-shims": "1.0.0",
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "split": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/split/-/split-1.0.0.tgz",
- "integrity": "sha1-xDlc5oOrzSVLwo/h2rtuXCfc/64=",
- "dev": true,
- "requires": {
- "through": "2.3.8"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "dev": true,
- "requires": {
- "safe-buffer": "5.1.1"
- }
- },
- "tap-out": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/tap-out/-/tap-out-2.0.0.tgz",
- "integrity": "sha1-4pCSskjFzYme3jSCIZAHl6aLmNI=",
- "dev": true,
- "requires": {
- "re-emitter": "1.1.3",
- "readable-stream": "2.2.9",
- "split": "1.0.0",
- "trim": "0.0.1"
- }
- }
+ "events-to-array": "1.1.2",
+ "js-yaml": "3.11.0",
+ "minipass": "2.2.4"
}
},
"tee": {
@@ -546,60 +269,6 @@
}
}
},
- "through": {
- "version": "2.3.8",
- "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
- "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
- "dev": true
- },
- "through2": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz",
- "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=",
- "dev": true,
- "requires": {
- "readable-stream": "2.3.4",
- "xtend": "4.0.1"
- },
- "dependencies": {
- "process-nextick-args": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
- "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
- "dev": true
- },
- "readable-stream": {
- "version": "2.3.4",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.4.tgz",
- "integrity": "sha512-vuYxeWYM+fde14+rajzqgeohAI7YoJcHE7kXDAc4Nk0EbuKnJfqtY9YtRkLo/tqkuF7MsBQRhPnPeyjYITp3ZQ==",
- "dev": true,
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "2.0.0",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "dev": true,
- "requires": {
- "safe-buffer": "5.1.1"
- }
- }
- }
- },
- "trim": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz",
- "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=",
- "dev": true
- },
"ts-node": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-4.1.0.tgz",
@@ -630,12 +299,6 @@
"strip-json-comments": "2.0.1"
}
},
- "util-deprecate": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
- "dev": true
- },
"v8flags": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.0.1.tgz",
@@ -645,10 +308,10 @@
"homedir-polyfill": "1.0.1"
}
},
- "xtend": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
- "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
+ "yallist": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz",
+ "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=",
"dev": true
},
"yn": {
diff --git a/clients/ts/FunctionalTests/package.json b/clients/ts/FunctionalTests/package.json
index 2d9d1ade72b7..6ed723020eb3 100644
--- a/clients/ts/FunctionalTests/package.json
+++ b/clients/ts/FunctionalTests/package.json
@@ -10,8 +10,7 @@
"@types/node": "^9.4.6",
"debug": "^3.1.0",
"es6-promise": "^4.2.2",
- "tap-spec": "^4.1.1",
- "tap-teamcity": "^3.0.2",
+ "tap-parser": "^7.0.0",
"tee": "^0.2.0",
"ts-node": "^4.1.0"
},
diff --git a/clients/ts/FunctionalTests/selenium/run-ci-tests.ts b/clients/ts/FunctionalTests/selenium/run-ci-tests.ts
index dd71ddadb338..183c388384db 100644
--- a/clients/ts/FunctionalTests/selenium/run-ci-tests.ts
+++ b/clients/ts/FunctionalTests/selenium/run-ci-tests.ts
@@ -2,9 +2,6 @@ import { ChildProcess, spawn, spawnSync } from "child_process";
import { existsSync } from "fs";
import * as path from "path";
-import * as tapTeamCity from "tap-teamcity";
-import * as tee from "tee";
-
const teamcity = !!process.env.TEAMCITY_VERSION;
let force = process.env.ASPNETCORE_SIGNALR_FORCE_BROWSER_TESTS === "true";
@@ -56,7 +53,11 @@ function getChromeBinaryPath(): string {
switch (process.platform) {
case "win32":
// tslint:disable-next-line:no-string-literal
- return path.resolve(process.env.LOCALAPPDATA, "Google", "Chrome", "Application", "chrome.exe");
+ let candidatePath = path.resolve(process.env["ProgramFiles(x86)"], "Google", "Chrome", "Application", "chrome.exe");
+ if (!existsSync(candidatePath)) {
+ candidatePath = path.resolve(process.env.LOCALAPPDATA, "Google", "Chrome", "Application", "chrome.exe");
+ }
+ return candidatePath;
case "darwin":
return path.resolve("/", "Applications", "Google Chrome.app", "Contents", "MacOS", "Google Chrome");
case "linux":
@@ -83,11 +84,22 @@ if (verbose) {
args.push("--verbose");
}
-const testProcess = spawn("npm", args, { cwd: path.resolve(__dirname, "..") });
-testProcess.stderr.pipe(process.stderr);
-if (teamcity) {
- testProcess.stdout.pipe(tapTeamCity()).pipe(process.stdout);
+let command = "npm";
+
+if (process.platform === "win32") {
+ // NPM is a cmd file, and it's tricky to "spawn". Instead, we'll find the NPM js file and use process.execPath to locate node.exe and run it directly
+ const npmPath = path.resolve(process.execPath, "..", "node_modules", "npm", "bin", "npm-cli.js");
+ if (!existsSync(npmPath)) {
+ failPrereq(`Unable to locate npm command line at '${npmPath}'`);
+ }
+
+ args.unshift(npmPath);
+ command = process.execPath;
}
+console.log(`running: ${command} ${args.join(" ")}`);
+
+const testProcess = spawn(command, args, { cwd: path.resolve(__dirname, "..") });
+testProcess.stderr.pipe(process.stderr);
testProcess.stdout.pipe(process.stdout);
testProcess.on("close", (code) => process.exit(code));
\ No newline at end of file
diff --git a/clients/ts/FunctionalTests/selenium/run-tests.ts b/clients/ts/FunctionalTests/selenium/run-tests.ts
index a7fea9056699..c74603b12c56 100644
--- a/clients/ts/FunctionalTests/selenium/run-tests.ts
+++ b/clients/ts/FunctionalTests/selenium/run-tests.ts
@@ -4,8 +4,6 @@ import { EOL } from "os";
import * as path from "path";
import { PassThrough, Readable } from "stream";
-import * as tapSpec from "tap-spec";
-
import { run } from "../../webdriver-tap-runner/lib";
import * as _debug from "debug";
@@ -71,16 +69,12 @@ function waitForMatch(command: string, process: ChildProcess, regex: RegExp): Pr
});
}
-let raw = false;
let configuration = "Debug";
let chromePath: string;
let spec: string;
for (let i = 2; i < process.argv.length; i += 1) {
switch (process.argv[i]) {
- case "--raw":
- raw = true;
- break;
case "--configuration":
i += 1;
configuration = process.argv[i];
@@ -104,16 +98,6 @@ if (chromePath) {
debug(`Using Google Chrome at: '${chromePath}'`);
}
-function createOutput() {
- if (raw) {
- return process.stdout;
- } else {
- const output = tapSpec();
- output.pipe(process.stdout);
- return output;
- }
-}
-
(async () => {
try {
const serverPath = path.resolve(__dirname, "..", "bin", configuration, "netcoreapp2.1", "FunctionalTests.dll");
@@ -150,7 +134,7 @@ function createOutput() {
const failureCount = await run("SignalR Browser Functional Tests", {
browser: "chrome",
chromeBinaryPath: chromePath,
- output: createOutput(),
+ output: process.stdout,
url,
webdriverPort: 9515,
});
diff --git a/clients/ts/FunctionalTests/ts/ConnectionTests.ts b/clients/ts/FunctionalTests/ts/ConnectionTests.ts
index 9744a5c268ab..58aae5f2da81 100644
--- a/clients/ts/FunctionalTests/ts/ConnectionTests.ts
+++ b/clients/ts/FunctionalTests/ts/ConnectionTests.ts
@@ -3,12 +3,13 @@
import { HttpConnection, LogLevel, TransferFormat, TransportType } from "@aspnet/signalr";
import { eachTransport, ECHOENDPOINT_URL } from "./Common";
+import { TestLogger } from "./TestLogger";
describe("connection", () => {
it("can connect to the server without specifying transport explicitly", (done) => {
const message = "Hello World!";
const connection = new HttpConnection(ECHOENDPOINT_URL, {
- logger: LogLevel.Trace,
+ logger: TestLogger.instance,
});
let received = "";
@@ -38,7 +39,7 @@ describe("connection", () => {
// the url should be resolved relative to the document.location.host
// and the leading '/' should be automatically added to the url
const connection = new HttpConnection("echo", {
- logger: LogLevel.Trace,
+ logger: TestLogger.instance,
transport: transportType,
});
diff --git a/clients/ts/FunctionalTests/ts/HubConnectionTests.ts b/clients/ts/FunctionalTests/ts/HubConnectionTests.ts
index faff3b1fabb1..2f7a92c51b05 100644
--- a/clients/ts/FunctionalTests/ts/HubConnectionTests.ts
+++ b/clients/ts/FunctionalTests/ts/HubConnectionTests.ts
@@ -5,6 +5,7 @@ import { HubConnection, JsonHubProtocol, LogLevel, TransportType } from "@aspnet
import { MessagePackHubProtocol } from "@aspnet/signalr-protocol-msgpack";
import { eachTransport, eachTransportAndProtocol } from "./Common";
+import { TestLogger } from "./TestLogger";
const TESTHUBENDPOINT_URL = "/testhub";
const TESTHUB_NOWEBSOCKETS_ENDPOINT_URL = "/testhub-nowebsockets";
@@ -16,7 +17,7 @@ describe("hubConnection", () => {
const message = "你好,世界!";
const hubConnection = new HubConnection(TESTHUBENDPOINT_URL, {
- logger: LogLevel.Trace,
+ logger: TestLogger.instance,
protocol,
transport: transportType,
});
@@ -43,7 +44,7 @@ describe("hubConnection", () => {
const message = "你好,世界!";
const hubConnection = new HubConnection(TESTHUBENDPOINT_URL, {
- logger: LogLevel.Trace,
+ logger: TestLogger.instance,
protocol,
transport: transportType,
});
@@ -66,7 +67,7 @@ describe("hubConnection", () => {
it("can invoke server method structural object and receive structural result", (done) => {
const hubConnection = new HubConnection(TESTHUBENDPOINT_URL, {
- logger: LogLevel.Trace,
+ logger: TestLogger.instance,
protocol,
transport: transportType,
});
@@ -92,7 +93,7 @@ describe("hubConnection", () => {
it("can stream server method and receive result", (done) => {
const hubConnection = new HubConnection(TESTHUBENDPOINT_URL, {
- logger: LogLevel.Trace,
+ logger: TestLogger.instance,
protocol,
transport: transportType,
});
@@ -126,7 +127,7 @@ describe("hubConnection", () => {
it("rethrows an exception from the server when invoking", (done) => {
const errorMessage = "An unexpected error occurred invoking 'ThrowException' on the server. InvalidOperationException: An error occurred.";
const hubConnection = new HubConnection(TESTHUBENDPOINT_URL, {
- logger: LogLevel.Trace,
+ logger: TestLogger.instance,
protocol,
transport: transportType,
});
@@ -150,7 +151,7 @@ describe("hubConnection", () => {
it("throws an exception when invoking streaming method with invoke", (done) => {
const hubConnection = new HubConnection(TESTHUBENDPOINT_URL, {
- logger: LogLevel.Trace,
+ logger: TestLogger.instance,
protocol,
transport: transportType,
});
@@ -174,7 +175,7 @@ describe("hubConnection", () => {
it("throws an exception when receiving a streaming result for method called with invoke", (done) => {
const hubConnection = new HubConnection(TESTHUBENDPOINT_URL, {
- logger: LogLevel.Trace,
+ logger: TestLogger.instance,
protocol,
transport: transportType,
});
@@ -199,7 +200,7 @@ describe("hubConnection", () => {
it("rethrows an exception from the server when streaming", (done) => {
const errorMessage = "An unexpected error occurred invoking 'StreamThrowException' on the server. InvalidOperationException: An error occurred.";
const hubConnection = new HubConnection(TESTHUBENDPOINT_URL, {
- logger: LogLevel.Trace,
+ logger: TestLogger.instance,
protocol,
transport: transportType,
});
@@ -228,7 +229,7 @@ describe("hubConnection", () => {
it("throws an exception when invoking hub method with stream", (done) => {
const hubConnection = new HubConnection(TESTHUBENDPOINT_URL, {
- logger: LogLevel.Trace,
+ logger: TestLogger.instance,
protocol,
transport: transportType,
});
@@ -257,7 +258,7 @@ describe("hubConnection", () => {
it("can receive server calls", (done) => {
const hubConnection = new HubConnection(TESTHUBENDPOINT_URL, {
- logger: LogLevel.Trace,
+ logger: TestLogger.instance,
protocol,
transport: transportType,
});
@@ -289,7 +290,7 @@ describe("hubConnection", () => {
it("can receive server calls without rebinding handler when restarted", (done) => {
const hubConnection = new HubConnection(TESTHUBENDPOINT_URL, {
- logger: LogLevel.Trace,
+ logger: TestLogger.instance,
protocol,
transport: transportType,
});
@@ -346,7 +347,7 @@ describe("hubConnection", () => {
it("closed with error if hub cannot be created", (done) => {
const hubConnection = new HubConnection("http://" + document.location.host + "/uncreatable", {
- logger: LogLevel.Trace,
+ logger: TestLogger.instance,
protocol,
transport: transportType,
});
@@ -360,7 +361,7 @@ describe("hubConnection", () => {
it("can handle different types", (done) => {
const hubConnection = new HubConnection(TESTHUBENDPOINT_URL, {
- logger: LogLevel.Trace,
+ logger: TestLogger.instance,
protocol,
transport: transportType,
});
@@ -408,7 +409,7 @@ describe("hubConnection", () => {
const message = "你好,世界!";
const hubConnection = new HubConnection(TESTHUBENDPOINT_URL, {
- logger: LogLevel.Trace,
+ logger: TestLogger.instance,
protocol,
transport: transportType,
});
@@ -463,7 +464,7 @@ describe("hubConnection", () => {
const jwtToken = await getJwtToken("http://" + document.location.host + "/generateJwtToken");
const hubConnection = new HubConnection("/authorizedhub", {
accessTokenFactory: () => jwtToken,
- logger: LogLevel.Trace,
+ logger: TestLogger.instance,
transport: transportType,
});
hubConnection.onclose((error) => {
@@ -487,7 +488,7 @@ describe("hubConnection", () => {
if (transportType !== TransportType.LongPolling) {
it("terminates if no messages received within timeout interval", (done) => {
const hubConnection = new HubConnection(TESTHUBENDPOINT_URL, {
- logger: LogLevel.Trace,
+ logger: TestLogger.instance,
timeoutInMilliseconds: 100,
transport: transportType,
});
@@ -511,7 +512,7 @@ describe("hubConnection", () => {
if (typeof EventSource !== "undefined") {
it("allows Server-Sent Events when negotiating for JSON protocol", async (done) => {
const hubConnection = new HubConnection(TESTHUB_NOWEBSOCKETS_ENDPOINT_URL, {
- logger: LogLevel.Trace,
+ logger: TestLogger.instance,
protocol: new JsonHubProtocol(),
});
@@ -529,7 +530,7 @@ describe("hubConnection", () => {
it("skips Server-Sent Events when negotiating for MsgPack protocol", async (done) => {
const hubConnection = new HubConnection(TESTHUB_NOWEBSOCKETS_ENDPOINT_URL, {
- logger: LogLevel.Trace,
+ logger: TestLogger.instance,
protocol: new MessagePackHubProtocol(),
});
diff --git a/clients/ts/FunctionalTests/ts/TestLogger.ts b/clients/ts/FunctionalTests/ts/TestLogger.ts
new file mode 100644
index 000000000000..e3fa685dde42
--- /dev/null
+++ b/clients/ts/FunctionalTests/ts/TestLogger.ts
@@ -0,0 +1,17 @@
+import { ILogger, LogLevel } from "@aspnet/signalr";
+
+export class TestLogger implements ILogger {
+ public static instance: TestLogger = new TestLogger();
+
+ public messages: Array<[LogLevel, string]> = [];
+
+ public log(logLevel: LogLevel, message: string): void {
+ this.messages.push([logLevel, message]);
+ }
+
+ public static getMessagesAndReset(): Array<[LogLevel, string]> {
+ const messages = TestLogger.instance.messages;
+ TestLogger.instance = new TestLogger();
+ return messages;
+ }
+}
diff --git a/clients/ts/FunctionalTests/ts/WebDriverReporter.ts b/clients/ts/FunctionalTests/ts/WebDriverReporter.ts
index 85ca1196b9a8..dc81e8a6946d 100644
--- a/clients/ts/FunctionalTests/ts/WebDriverReporter.ts
+++ b/clients/ts/FunctionalTests/ts/WebDriverReporter.ts
@@ -1,3 +1,5 @@
+import { LogLevel } from "@aspnet/signalr";
+import { TestLogger } from "./TestLogger";
import { getParameterByName } from "./Utils";
function formatValue(v: any): string {
@@ -16,6 +18,7 @@ class WebDriverReporter implements jasmine.CustomReporter {
private element: HTMLDivElement;
private specCounter: number = 1; // TAP number start at 1
private recordCounter: number = 0;
+ private concurrentSpecCount: number = 0;
constructor(private document: Document, show: boolean = false) {
// We write to the DOM because it's the most compatible way for WebDriver to read.
@@ -36,7 +39,16 @@ class WebDriverReporter implements jasmine.CustomReporter {
this.taplog(`1..${suiteInfo.totalSpecsDefined}`);
}
+ public specStarted(result: jasmine.CustomReporterResult): void {
+ this.concurrentSpecCount += 1;
+ if (this.concurrentSpecCount > 1) {
+ throw new Error("Unexpected concurrent tests!");
+ }
+ }
+
public specDone(result: jasmine.CustomReporterResult): void {
+ this.concurrentSpecCount -= 1;
+ const messages = TestLogger.getMessagesAndReset();
if (result.status === "disabled") {
return;
} else if (result.status === "failed") {
@@ -44,17 +56,29 @@ class WebDriverReporter implements jasmine.CustomReporter {
// Just report the first failure
this.taplog(" ---");
- for (const expectation of result.failedExpectations) {
- // Include YAML block with failed expectations
- this.taplog(` - message: ${expectation.message}`);
- if (expectation.matcherName) {
- this.taplog(` operator: ${expectation.matcherName}`);
+ if (result.failedExpectations.length > 0) {
+ this.taplog(" - messages:");
+ for (const expectation of result.failedExpectations) {
+ // Include YAML block with failed expectations
+ this.taplog(` - message: ${expectation.message}`);
+ if (expectation.matcherName) {
+ this.taplog(` operator: ${expectation.matcherName}`);
+ }
+ if (expectation.expected) {
+ this.taplog(` expected: ${formatValue(expectation.expected)}`);
+ }
+ if (expectation.actual) {
+ this.taplog(` actual: ${formatValue(expectation.actual)}`);
+ }
}
- if (expectation.expected) {
- this.taplog(` expected: ${formatValue(expectation.expected)}`);
- }
- if (expectation.actual) {
- this.taplog(` actual: ${formatValue(expectation.actual)}`);
+ }
+
+ // Report log messages
+ if (messages.length > 0) {
+ this.taplog(" - logs: ");
+ for (const [level, message] of messages) {
+ this.taplog(` - level: ${LogLevel[level]}`);
+ this.taplog(` message: ${message}`);
}
}
this.taplog(" ...");