collect log messages during browser tests (#1670)

This commit is contained in:
Andrew Stanton-Nurse 2018-03-29 10:11:18 -07:00 committed by GitHub
parent 7a53e07623
commit a4d0bf2e3a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 146 additions and 445 deletions

View File

@ -33,7 +33,7 @@
<Target Name="RunBrowserTests">
<Message Text="Running TypeScript client Browser tests" Importance="high" />
<Exec Command="npm run ci-test -- --configuration $(Configuration) -v" WorkingDirectory="$(RepositoryRoot)clients/ts/FunctionalTests" IgnoreStandardErrorWarningFormat="true" />
<Exec Command="npm run ci-test -- --configuration $(Configuration)" WorkingDirectory="$(RepositoryRoot)clients/ts/FunctionalTests" IgnoreStandardErrorWarningFormat="true" />
</Target>
<PropertyGroup>

View File

@ -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=",
"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": {
"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==",
"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": {

View File

@ -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"
},

View File

@ -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));

View File

@ -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,
});

View File

@ -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,
});

View File

@ -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(),
});

View File

@ -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;
}
}

View File

@ -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(" ...");