From 9f4fda13e7b8db6779ed5de5e4e72b7654c760c8 Mon Sep 17 00:00:00 2001 From: Srinath Narayanan Date: Wed, 11 Nov 2020 04:53:04 -0800 Subject: [PATCH] initial commit for notbooks pupeteer tests --- package-lock.json | 355 +++++++++++++++++- package.json | 3 +- src/Contracts/ExplorerContracts.ts | 4 +- src/Explorer/Explorer.ts | 7 + src/Explorer/Panes/UploadFilePane.html | 15 +- src/TestExplorer.ts | 319 ++++++++++++++++ src/testExplorer.html | 22 ++ test/notebooks/notebookTestUtils.ts | 18 + .../testNotebooks/GettingStarted.ipynb | 110 ++++++ .../uploadRunAndDeleteNotebook.spec.ts | 82 ++++ test/utils/shared.ts | 2 + webpack.config.js | 6 + 12 files changed, 921 insertions(+), 22 deletions(-) create mode 100644 src/TestExplorer.ts create mode 100644 src/testExplorer.html create mode 100644 test/notebooks/notebookTestUtils.ts create mode 100644 test/notebooks/testNotebooks/GettingStarted.ipynb create mode 100644 test/notebooks/uploadRunAndDeleteNotebook.spec.ts diff --git a/package-lock.json b/package-lock.json index 3bfb5bc6b..0f4722727 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,113 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@azure/abort-controller": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-1.0.1.tgz", + "integrity": "sha512-wP2Jw6uPp8DEDy0n4KNidvwzDjyVV2xnycEIq7nPzj1rHyb/r+t3OPeNT1INZePP2wy5ZqlwyuyOMTi0ePyY1A==", + "requires": { + "tslib": "^1.9.3" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "@azure/core-auth": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.1.3.tgz", + "integrity": "sha512-A4xigW0YZZpkj1zK7dKuzbBpGwnhEcRk6WWuIshdHC32raR3EQ1j6VA9XZqE+RFsUgH6OAmIK5BWIz+mZjnd6Q==", + "requires": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-tracing": "1.0.0-preview.8", + "@opentelemetry/api": "^0.6.1", + "tslib": "^2.0.0" + }, + "dependencies": { + "@azure/core-tracing": { + "version": "1.0.0-preview.8", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.0-preview.8.tgz", + "integrity": "sha512-ZKUpCd7Dlyfn7bdc+/zC/sf0aRIaNQMDuSj2RhYRFe3p70hVAnYGp3TX4cnG2yoEALp/LTj/XnZGQ8Xzf6Ja/Q==", + "requires": { + "@opencensus/web-types": "0.0.7", + "@opentelemetry/api": "^0.6.1", + "tslib": "^1.10.0" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "@opentelemetry/api": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-0.6.1.tgz", + "integrity": "sha512-wpufGZa7tTxw7eAsjXJtiyIQ42IWQdX9iUQp7ACJcKo1hCtuhLU+K2Nv1U6oRwT1oAlZTE6m4CgWKZBhOiau3Q==", + "requires": { + "@opentelemetry/context-base": "^0.6.1" + } + } + } + }, + "@azure/core-http": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@azure/core-http/-/core-http-1.1.9.tgz", + "integrity": "sha512-wM0HMRNQaE2NtTHb+9FXF7uxUqaAHFTMVu6OzlEll6gUGybcDqM7+9Oklp33BhEfq+ZumpCoqxq3njNbMHuf/w==", + "requires": { + "@azure/abort-controller": "^1.0.0", + "@azure/core-auth": "^1.1.3", + "@azure/core-tracing": "1.0.0-preview.9", + "@azure/logger": "^1.0.0", + "@opentelemetry/api": "^0.10.2", + "@types/node-fetch": "^2.5.0", + "@types/tunnel": "^0.0.1", + "form-data": "^3.0.0", + "node-fetch": "^2.6.0", + "process": "^0.11.10", + "tough-cookie": "^4.0.0", + "tslib": "^2.0.0", + "tunnel": "^0.0.6", + "uuid": "^8.1.0", + "xml2js": "^0.4.19" + }, + "dependencies": { + "form-data": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.0.tgz", + "integrity": "sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "tough-cookie": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "requires": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" + } + } + } + }, + "@azure/core-tracing": { + "version": "1.0.0-preview.9", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.0-preview.9.tgz", + "integrity": "sha512-zczolCLJ5QG42AEPQ+Qg9SRYNUyB+yZ5dzof4YEc+dyWczO9G2sBqbAjLB7IqrsdHN2apkiB2oXeDKCsq48jug==", + "requires": { + "@opencensus/web-types": "0.0.7", + "@opentelemetry/api": "^0.10.2", + "tslib": "^2.0.0" + } + }, "@azure/cosmos": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/@azure/cosmos/-/cosmos-3.9.0.tgz", @@ -53,6 +160,46 @@ } } }, + "@azure/identity": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-1.1.0.tgz", + "integrity": "sha512-S4jYqegLWXIwVnkiArFlcTA7KOZmv+LMhQeQJhnmYy/CxrJHyIAEQyJ7qsrSt58bSyDZI2NkmKUBKaYGZU3/5g==", + "requires": { + "@azure/core-http": "^1.1.6", + "@azure/core-tracing": "1.0.0-preview.9", + "@azure/logger": "^1.0.0", + "@opentelemetry/api": "^0.10.2", + "events": "^3.0.0", + "jws": "^4.0.0", + "keytar": "^5.4.0", + "msal": "^1.0.2", + "qs": "^6.7.0", + "tslib": "^2.0.0", + "uuid": "^8.1.0" + }, + "dependencies": { + "qs": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz", + "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==" + } + } + }, + "@azure/logger": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.0.0.tgz", + "integrity": "sha512-g2qLDgvmhyIxR3JVS8N67CyIOeFRKQlX/llxYJQr1OSGQqM3HTpVP8MjmjcEKbL/OIt2N9C9UFaNQuKOw1laOA==", + "requires": { + "tslib": "^1.9.3" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, "@babel/code-frame": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", @@ -3426,6 +3573,31 @@ } } }, + "@opencensus/web-types": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/@opencensus/web-types/-/web-types-0.0.7.tgz", + "integrity": "sha512-xB+w7ZDAu3YBzqH44rCmG9/RlrOmFuDPt/bpf17eJr8eZSrLt7nc7LnWdxM9Mmoj/YKMHpxRg28txu3TcpiL+g==" + }, + "@opentelemetry/api": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-0.10.2.tgz", + "integrity": "sha512-GtpMGd6vkzDMYcpu2t9LlhEgMy/SzBwRnz48EejlRArYqZzqSzAsKmegUK7zHgl+EOIaK9mKHhnRaQu3qw20cA==", + "requires": { + "@opentelemetry/context-base": "^0.10.2" + }, + "dependencies": { + "@opentelemetry/context-base": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-base/-/context-base-0.10.2.tgz", + "integrity": "sha512-hZNKjKOYsckoOEgBziGMnBcX0M7EtstnCmwz5jZUOUYwlZ+/xxX6z3jPu1XVO2Jivk0eLfuP9GP+vFD49CMetw==" + } + } + }, + "@opentelemetry/context-base": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-base/-/context-base-0.6.1.tgz", + "integrity": "sha512-5bHhlTBBq82ti3qPT15TRxkYTFPPQWbnkkQkmHPtqiS1XcTB69cEKd3Jm7Cfi/vkPoyxapmePE9tyA7EzLt8SQ==" + }, "@peculiar/asn1-schema": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-1.1.2.tgz", @@ -4108,8 +4280,7 @@ "@types/node": { "version": "12.11.1", "resolved": "https://registry.npmjs.org/@types/node/-/node-12.11.1.tgz", - "integrity": "sha512-TJtwsqZ39pqcljJpajeoofYRfeZ7/I/OMUQ5pR4q5wOKf2ocrUvBAZUMhWsOvKx3dVc/aaV5GluBivt0sWqA5A==", - "dev": true + "integrity": "sha512-TJtwsqZ39pqcljJpajeoofYRfeZ7/I/OMUQ5pR4q5wOKf2ocrUvBAZUMhWsOvKx3dVc/aaV5GluBivt0sWqA5A==" }, "@types/node-fetch": { "version": "2.5.7", @@ -4307,6 +4478,14 @@ "integrity": "sha512-kAMOjud0Nw3HPY0Cu8cTFk0LVya8skY+ajb2rgrSahPQ6AreN0cpGBNrs8Kjlu9EhFIeh5cp7phovL7v9HrPdQ==", "dev": true }, + "@types/tunnel": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@types/tunnel/-/tunnel-0.0.1.tgz", + "integrity": "sha512-AOqu6bQu5MSWwYvehMXLukFHnupHrpZ8nvgae5Ggie9UwzDR1CCwoXgSSWNZJuyOlCdfdsWMA5F2LlmvyoTv8A==", + "requires": { + "@types/node": "*" + } + }, "@types/uglify-js": { "version": "3.11.0", "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.11.0.tgz", @@ -5935,7 +6114,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", - "dev": true, "requires": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -5946,7 +6124,6 @@ "version": "5.6.0", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", - "dev": true, "requires": { "base64-js": "^1.0.2", "ieee754": "^1.1.4" @@ -5956,7 +6133,6 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -6284,6 +6460,11 @@ "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", "dev": true }, + "buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" + }, "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", @@ -8475,6 +8656,14 @@ "safer-buffer": "^2.1.0" } }, + "ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -9223,8 +9412,7 @@ "events": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz", - "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==", - "dev": true + "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==" }, "eventsource": { "version": "1.0.7", @@ -9314,6 +9502,12 @@ } } }, + "expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "optional": true + }, "expand-tilde": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", @@ -10136,8 +10330,7 @@ "fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" }, "fs-exists-sync": { "version": "0.1.0", @@ -10396,6 +10589,12 @@ "assert-plus": "^1.0.0" } }, + "github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=", + "optional": true + }, "glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", @@ -14072,6 +14271,35 @@ "integrity": "sha512-aWgeGFW67BP3e5181Ep1Fv2v8z//iBJfrvyTnq8wG86vEESwmonn1zPBJ0VfmT9CJq2FIT0VsETtrNFm2a+SHA==", "dev": true }, + "jwa": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "jws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "requires": { + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + }, + "keytar": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/keytar/-/keytar-5.6.0.tgz", + "integrity": "sha512-ueulhshHSGoryfRXaIvTj0BV1yB0KddBGhGoqCxSN9LR1Ks1GKuuCdVhF+2/YOs5fMl6MlTI9On1a4DHDXoTow==", + "optional": true, + "requires": { + "nan": "2.14.1", + "prebuild-install": "5.3.3" + } + }, "killable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", @@ -15123,8 +15351,7 @@ "mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" }, "moment": { "version": "2.29.0", @@ -15190,6 +15417,21 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "msal": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/msal/-/msal-1.4.3.tgz", + "integrity": "sha512-C90MhgzcBuTSR2BOQ/LQryY1CZVESQLJDdmRDWSsaVde+zwZ2iXD0fWw7zeBd5TzfUCiJEXZVs4lFJ8d/IGbiQ==", + "requires": { + "tslib": "^1.9.3" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, "multicast-dns": { "version": "6.2.3", "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", @@ -15234,6 +15476,12 @@ "to-regex": "^3.0.1" } }, + "napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", + "optional": true + }, "native-promise-only": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/native-promise-only/-/native-promise-only-0.8.1.tgz", @@ -15328,6 +15576,15 @@ "lower-case": "^1.1.1" } }, + "node-abi": { + "version": "2.19.1", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.19.1.tgz", + "integrity": "sha512-HbtmIuByq44yhAzK7b9j/FelKlHYISKQn0mtvcBrU5QBkhoCMp5bu8Hv5AI34DcKfOAcJBcOEMwLlwO62FFu9A==", + "optional": true, + "requires": { + "semver": "^5.4.1" + } + }, "node-abort-controller": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-1.1.0.tgz", @@ -15336,8 +15593,7 @@ "node-fetch": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", - "dev": true + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" }, "node-forge": { "version": "0.10.0", @@ -15473,6 +15729,12 @@ "integrity": "sha512-DD5vebQLg8jLCOzwupn954fbIiZht05DAZs0k2u8NStSe6h9XdsuIQL8hSRKYiU8WUQRznmSDrKGbv3ObOmC7g==", "dev": true }, + "noop-logger": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", + "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=", + "optional": true + }, "nopt": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", @@ -16491,6 +16753,40 @@ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" }, + "prebuild-install": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.3.tgz", + "integrity": "sha512-GV+nsUXuPW2p8Zy7SarF/2W/oiK8bFQgJcncoJ0d7kRpekEA0ftChjfEaF9/Y+QJEc/wFR7RAEa8lYByuUIe2g==", + "optional": true, + "requires": { + "detect-libc": "^1.0.3", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "napi-build-utils": "^1.0.1", + "node-abi": "^2.7.0", + "noop-logger": "^0.1.1", + "npmlog": "^4.0.1", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^3.0.3", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0", + "which-pm-runs": "^1.0.0" + }, + "dependencies": { + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "optional": true, + "requires": { + "minimist": "^1.2.5" + } + } + } + }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", @@ -19352,7 +19648,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.0.tgz", "integrity": "sha512-9uW5iDvrIMCVpvasdFHW0wJPez0K4JnMZtsuIeDI7HyMGJNxmDZDOCQROr7lXyS+iL/QMpj07qcjGYTSdRFXUg==", - "dev": true, "requires": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", @@ -19364,7 +19659,6 @@ "version": "2.1.4", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.4.tgz", "integrity": "sha512-o3pS2zlG4gxr67GmFYBLlq+dM8gyRGUOvsrHclSkvtVtQbjV0s/+ZE8OpICbaj8clrX3tjeHngYGP7rweaBnuw==", - "dev": true, "requires": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", @@ -19377,7 +19671,6 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -19875,6 +20168,11 @@ "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", "dev": true }, + "tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==" + }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -20146,8 +20444,7 @@ "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" }, "unpipe": { "version": "1.0.0", @@ -21378,6 +21675,12 @@ "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" }, + "which-pm-runs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", + "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=", + "optional": true + }, "wide-align": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", @@ -21514,6 +21817,22 @@ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" }, + "xml2js": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", + "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", + "requires": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "dependencies": { + "xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" + } + } + }, "xmlbuilder": { "version": "8.2.2", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-8.2.2.tgz", diff --git a/package.json b/package.json index 76cd0da5e..836b518fb 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "dependencies": { "@azure/cosmos": "3.9.0", "@azure/cosmos-language-service": "0.0.4", + "@azure/identity": "1.1.0", "@jupyterlab/services": "6.0.0-rc.2", "@jupyterlab/terminal": "3.0.0-rc.2", "@microsoft/applicationinsights-web": "2.5.9", @@ -187,7 +188,7 @@ "pack:fast": "node --max_old_space_size=10196 ./node_modules/webpack/bin/webpack.js --mode development --progress", "copyToConsumers": "node copyToConsumers", "test": "rimraf coverage && jest", - "test:e2e": "jest -c ./jest.config.e2e.js --detectOpenHandles", + "test:e2e": "jest -c ./jest.config.e2e.js --detectOpenHandles test/notebooks/uploadRunAndDeleteNotebook.spec.ts", "watch": "npm run start", "wait-for-server": "wait-on -t 240000 -i 5000 -v https-get://0.0.0.0:1234/", "build:ase": "gulp build:ase", diff --git a/src/Contracts/ExplorerContracts.ts b/src/Contracts/ExplorerContracts.ts index 088462dbd..96171d30b 100644 --- a/src/Contracts/ExplorerContracts.ts +++ b/src/Contracts/ExplorerContracts.ts @@ -32,7 +32,9 @@ export enum MessageTypes { GetArcadiaToken, CreateWorkspace, CreateSparkPool, - RefreshDatabaseAccount + RefreshDatabaseAccount, + InitTestExplorer, + HideConnectScreen } export { Versions, ActionContracts, Diagnostics }; diff --git a/src/Explorer/Explorer.ts b/src/Explorer/Explorer.ts index 1c26debfa..94f9f506d 100644 --- a/src/Explorer/Explorer.ts +++ b/src/Explorer/Explorer.ts @@ -1724,6 +1724,8 @@ export default class Explorer { case MessageTypes.SendNotification: case MessageTypes.ClearNotification: case MessageTypes.LoadingStatus: + case MessageTypes.InitTestExplorer: + case MessageTypes.HideConnectScreen: return true; } } @@ -1742,6 +1744,10 @@ export default class Explorer { return; } + if (event.data.data.type === MessageTypes.HideConnectScreen) { + this.hideConnectExplorerForm(); + } + const message: any = event.data.data; const inputs: ViewModels.DataExplorerInputsFrame = message.inputs; @@ -2537,6 +2543,7 @@ export default class Explorer { const databaseAccountLocation = databaseAccount && databaseAccount.location.toLowerCase(); const disallowedLocationsUri = `${configContext.BACKEND_ENDPOINT}/api/disallowedLocations`; const authorizationHeader = getAuthorizationHeader(); + console.log("auth header:" + JSON.stringify(authorizationHeader)); try { const response = await fetch(disallowedLocationsUri, { method: "POST", diff --git a/src/Explorer/Panes/UploadFilePane.html b/src/Explorer/Panes/UploadFilePane.html index fc98419bb..ff815d130 100644 --- a/src/Explorer/Panes/UploadFilePane.html +++ b/src/Explorer/Panes/UploadFilePane.html @@ -50,13 +50,24 @@ id="fileImportLinkNotebook" data-bind="event: { click: onImportLinkClick, keypress: onImportLinkKeyPress }" > - upload files + upload files
- +
diff --git a/src/TestExplorer.ts b/src/TestExplorer.ts new file mode 100644 index 000000000..79701856a --- /dev/null +++ b/src/TestExplorer.ts @@ -0,0 +1,319 @@ +import "./Shared/appInsights"; +import * as _ from "underscore"; +import * as ko from "knockout"; +import { MessageTypes } from "./Contracts/ExplorerContracts"; +import "../less/hostedexplorer.less"; +import "./Explorer/Menus/NavBar/MeControlComponent.less"; +import * as ViewModels from "./Contracts/ViewModels"; +import { ClientSecretCredential } from "@azure/identity"; + +class TestExplorer { + public isButtonVisible: ko.Observable; + + constructor() { + this.isButtonVisible = ko.observable(true); + window.addEventListener("message", this.handleMessage.bind(this), false); + } + + private handleMessage(event: MessageEvent) { + if (event.data.type === MessageTypes.InitTestExplorer || event.data.type === MessageTypes.HideConnectScreen) { + this.sendMessageToExplorerFrame(event.data); + } + } + + private async AADLogin(): Promise { + const tenantId = "72f988bf-86f1-41af-91ab-2d7cd011db47"; + const clientId = "fd8753b0-0707-4e32-84e9-2532af865fb4"; + const clientSecret = "xGT82g3sO4AJ.C~G6dii5LP~6-yCit9J-h"; + + const credentials = new ClientSecretCredential(tenantId, clientId, clientSecret); + + const token = await credentials.getToken("https://management.core.windows.net/.default"); + + return token.token; + } + + public async postMessage(): Promise { + const token = await this.AADLogin(); + const content = { + type: MessageTypes.InitTestExplorer, + inputs: { + databaseAccount: { + id: + "/subscriptions/18f84a75-22a7-487c-a800-4e1bdad7779a/resourceGroups/srnara-cassandra-test/providers/Microsoft.DocumentDB/databaseAccounts/srnara-notebook", + name: "srnara-notebook", + location: "East US", + type: "Microsoft.DocumentDB/databaseAccounts", + kind: "GlobalDocumentDB", + tags: { defaultExperience: "Core (SQL)" }, + systemData: { createdAt: "2019-10-16T20:46:11.4096965Z" }, + properties: { + provisioningState: "Succeeded", + documentEndpoint: "https://srnara-notebook.documents.azure.com:443/", + publicNetworkAccess: "Enabled", + enableAutomaticFailover: false, + enableMultipleWriteLocations: true, + enablePartitionKeyMonitor: false, + isVirtualNetworkFilterEnabled: false, + virtualNetworkRules: [], + EnabledApiTypes: "Sql", + disableKeyBasedMetadataWriteAccess: false, + enableFreeTier: false, + enableAnalyticalStorage: true, + instanceId: "41978508-99b1-477d-9205-2d2f1ce7fc1a", + createMode: "Default", + databaseAccountOfferType: "Standard", + consistencyPolicy: { defaultConsistencyLevel: "Session", maxIntervalInSeconds: 5, maxStalenessPrefix: 100 }, + configurationOverrides: {}, + writeLocations: [ + { + id: "srnara-notebook-eastus", + locationName: "East US", + documentEndpoint: "https://srnara-notebook-eastus.documents.azure.com:443/", + provisioningState: "Succeeded", + failoverPriority: 0, + isZoneRedundant: false + } + ], + readLocations: [ + { + id: "srnara-notebook-eastus", + locationName: "East US", + documentEndpoint: "https://srnara-notebook-eastus.documents.azure.com:443/", + provisioningState: "Succeeded", + failoverPriority: 0, + isZoneRedundant: false + } + ], + locations: [ + { + id: "srnara-notebook-eastus", + locationName: "East US", + documentEndpoint: "https://srnara-notebook-eastus.documents.azure.com:443/", + provisioningState: "Succeeded", + failoverPriority: 0, + isZoneRedundant: false + } + ], + failoverPolicies: [{ id: "srnara-notebook-eastus", locationName: "East US", failoverPriority: 0 }], + cors: [], + capabilities: [], + ipRules: [], + backupPolicy: { + type: "Periodic", + periodicModeProperties: { backupIntervalInMinutes: 240, backupRetentionIntervalInHours: 8 } + } + } + }, + subscriptionId: "18f84a75-22a7-487c-a800-4e1bdad7779a", + resourceGroup: "srnara-cassandra-test", + authorizationToken: `Bearer ${token}`, + features: { + cacheextensionapp: "false", + detailednetworktelemetry: "false", + logexternaldomainlinks: "true", + enableextensionpreviewstamp: "true", + gctelemetry: "false", + mereactblade: "true", + paralleltokens: "false", + prefetchbrowsequerymanifest: "false", + prefetchtokensinparallel: "true", + pretick: "false", + reactdatafetch: "false", + shellworker: "true", + shellworkerassets: "true", + shellworkerbrowseprereqs: "true", + shellworkersubs: "true", + simplebatch: "false", + storageperf1: "false", + storageperf2: "false", + earlymenucontentvm: "false", + bladefullrenderx: "false", + controlstelemetry: "true", + noeffectflight: "true", + advisornotificationdays: "30", + advisornotificationpercent: "100", + allserviceswithoverview: "true", + argsharedqueries: "true", + argsubscriptions: "true", + armviewer: "true", + asyncsearch: "true", + azureconsole: "true", + azurehome: "true", + columnchooserreact: "true", + contactinfo: "true", + custombingsearch: "true", + dashboardalphaapi: "true", + dashboardautorefresh: "true", + dashboardautorefreshinterval: "60", + dashboardfeedback: "true", + dashboardnewpinexperience: "true", + dashboardpreviewapi: "true", + dashboardrefresh: "true", + devsatsurvey: "true", + deploy2020: "true", + enableregionmove: "true", + enablestartswithmdm: "true", + enhancedprint: "true", + essentialsjsonview: "true", + freelancer: "true", + guidedtour: "true", + helpcontentwhatsnewenabled: "true", + hidefavoritestars: "true", + hostingservicesuffix: "mpac", + hubsresourceaccessfromconfig: "true", + internalonly: "nobanner", + iriscore: "true", + iriscorealt: "true", + iriscoresurfacename: "88000327", + irissurfacename: "AzurePortal_Notifications_Preview", + landalltohome: "true", + loggraphcallwitharmtoken: "true", + meazblade: "true", + mistendpoint: "https://mist.int.monitor.azure.com", + nojqueryeval: "true", + nopdlearlymenucontentbundles: "true", + npsintervaldays: "90", + npspercent: "2.4", + npsshowportaluri: "true", + policyawarecontrols: "true", + prefetchtokens: "true", + prewarmingtesting: "true", + reactviewendpointindex: "1", + reloadafterdays: "5", + serverfetchedevents: "true", + sessionvalidity: "true", + settingsportalinstance: "mpac", + shadowargcall: "true", + showbugreportlink: "true", + showhovercard: "true", + sidebarhamburgermode: "true", + singlesignout: "true", + subscreditcheck: "true", + tenants2020: "true", + tilegallerycuration: "true", + upgradefromtrialbutton: "true", + argbrowseviews: "true", + argforoldbrowse: "true", + argforrgoverview: "true", + argtagsfilter: "true", + artbrowse: "true", + automationtasks: "true", + browsecuration: "default", + browsedialogcompactpills: "true", + browsedialogpills: "true", + browsefilterstelemetry: "true", + bypasstokencacheforcustomsignin: "true", + cloudsimplereservations: "true", + contactabilitybycountry: "true", + cryptoapihash: "true", + dashboardfilters: "true", + dashboardfiltersaddbutton: "true", + devnps: "true", + devnpsintervaldays: "45", + devnpspercent: "50.0", + enableaeoemails: "false", + enablee2emonitoring: "true", + enablelocationchange: "true", + experimentation: "false", + failajaxonnulltoken: "true", + fastencode: "true", + feedback: "true", + feedbackwithsupport: "true", + fullscreenblades: "true", + hidemodalsonsmallscreens: "true", + hidemodalswhendeeplinked: "true", + irismessagelimit: "1", + isworkbooksavailable: "true", + migratetomsal: "true", + mspexpert: "true", + mspfilter: "true", + mspinfo: "true", + newresourceapi: "true", + newsupportblade: "true", + nps: "true", + outagebanner: "true", + portalpolling: "true", + preact: "true", + preferredusername: "true", + prefetchdrafttoken: "true", + prefetchrecents: "true", + providers2019: "true", + pushtokens: "true", + removesubsdropdownlimit: "true", + reservationsinbrowse: "true", + reservehozscroll: "true", + resourcehealth: "true", + savedeploymentnotification: "true", + seetemplate: "true", + serveravatar: "true", + showpostcreatefeedbackoption: "true", + showservicehealthalerts: "true", + showworkflowappkindbrowse: "true", + supplementalbatchsize: "20", + tenantscoperedirect: "true", + tokencaching: "true", + usealertsv2blade: "true", + usemsallogin: "true", + zerosubsexperience: "true", + regionsegments: "true", + allservicesweave: "false", + bundlingkind: "DefaultPartitioner", + confighash: "CGZNcAynkOLM", + env: "ms", + l: "en.en-us", + pageversion: "6.659.0.25051.201105-0922", + prefetchhome: "false", + prewarmie: "false", + weaveblade: "true", + dataexplorersource: "https://localhost:1234/explorer.html", + experimentationflights: "settingsv2;mongoindexeditor" + }, + hasWriteAccess: true, + csmEndpoint: "https://management.azure.com", + dnsSuffix: "documents.azure.com", + serverId: "prod1", + extensionEndpoint: "/proxy", + subscriptionType: 3, + quotaId: "Internal_2014-09-01", + addCollectionDefaultFlight: "2", + isTryCosmosDBSubscription: false, + masterKey: "jB16xFppH34oIsrxhKytgqlGdq4n3UcHAD9J20jNosrOAzDKfAcvM1kfeBM49ccFxjpFW85Du2ISvrjdl7i4fg==", + loadDatabaseAccountTimestamp: 1604663109836, + dataExplorerVersion: "1.0.1", + sharedThroughputMinimum: 400, + sharedThroughputMaximum: 1000000, + sharedThroughputDefault: 400, + defaultCollectionThroughput: { + storage: "100", + throughput: { fixed: 400, unlimited: 400, unlimitedmax: 100000, unlimitedmin: 400, shared: 400 } + }, + flights: ["mongoindexeditor", "settingsv2"] + } as ViewModels.DataExplorerInputsFrame + }; + window.postMessage(content, window.location.href); + + const hideConnectContent = { + type: MessageTypes.HideConnectScreen + }; + window.postMessage(hideConnectContent, window.location.href); + this.isButtonVisible(false); + } + + private sendMessageToExplorerFrame(data: any): void { + const explorerFrame = document.getElementById("explorerMenu") as HTMLIFrameElement; + explorerFrame && + explorerFrame.contentDocument && + explorerFrame.contentDocument.referrer && + explorerFrame.contentWindow.postMessage( + { + signature: "pcIframe", + data: data + }, + explorerFrame.contentDocument.referrer || window.location.href + ); + } +} + +const testExplorer = new TestExplorer(); +ko.applyBindings(testExplorer); diff --git a/src/testExplorer.html b/src/testExplorer.html new file mode 100644 index 000000000..d0ab0e73c --- /dev/null +++ b/src/testExplorer.html @@ -0,0 +1,22 @@ + + + + + Azure Cosmos DB + + + + + + + + + + diff --git a/test/notebooks/notebookTestUtils.ts b/test/notebooks/notebookTestUtils.ts new file mode 100644 index 000000000..4472394a5 --- /dev/null +++ b/test/notebooks/notebookTestUtils.ts @@ -0,0 +1,18 @@ +import { Frame } from "puppeteer"; + +let testExplorerFrame: Frame; +export async function getTestExplorerFrame(): Promise { + if (testExplorerFrame) { + return testExplorerFrame; + } + + const prodUrl = "https://localhost:1234/testExplorer.html"; + await page.goto(prodUrl); + const buttonHandle = await page.waitForSelector("button"); + buttonHandle.click(); + + const handle = await page.waitForSelector("iframe"); + testExplorerFrame = await handle.contentFrame(); + await testExplorerFrame.waitForSelector(".galleryHeader"); + return testExplorerFrame; +} diff --git a/test/notebooks/testNotebooks/GettingStarted.ipynb b/test/notebooks/testNotebooks/GettingStarted.ipynb new file mode 100644 index 000000000..97cd39743 --- /dev/null +++ b/test/notebooks/testNotebooks/GettingStarted.ipynb @@ -0,0 +1,110 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": "# Getting started with Cosmos notebooks\nIn this notebook, we'll learn how to use Cosmos notebook features. We'll create a database and container, import some sample data in a container in Azure Cosmos DB and run some queries over it." + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": "### Create new database and container\n\nTo connect to the service, you can use our built-in instance of ```cosmos_client```. This is a ready to use instance of [CosmosClient](https://docs.microsoft.com/python/api/azure-cosmos/azure.cosmos.cosmos_client.cosmosclient?view=azure-python) from our Python SDK. It already has the context of this account baked in. We'll use ```cosmos_client``` to create a new database called **RetailDemo** and container called **WebsiteData**.\n\nOur dataset will contain events that occurred on the website - e.g. a user viewing an item, adding it to their cart, or purchasing it. We will partition by CartId, which represents the individual cart of each user. This will give us an even distribution of throughput and storage in our container. Learn more about how to [choose a good partition key.](https://docs.microsoft.com/azure/cosmos-db/partition-data)" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "trusted": false + }, + "outputs": [], + "source": "import azure.cosmos\nfrom azure.cosmos.partition_key import PartitionKey\n\ndatabase = cosmos_client.create_database_if_not_exists('RetailDemo')\nprint('Database RetailDemo created')\n\ncontainer = database.create_container_if_not_exists(id='WebsiteData', partition_key=PartitionKey(path='/CartID'))\nprint('Container WebsiteData created')\n" + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": "#### Set the default database and container context to the new resources\n\nWe can use the ```%database {database_id}``` and ```%container {container_id}``` syntax." + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "trusted": false + }, + "outputs": [], + "source": "%database RetailDemo" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "trusted": false + }, + "outputs": [], + "source": "%container WebsiteData" + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": "### Load in sample JSON data and insert into the container. \nWe'll use the **%%upload** magic function to insert items into the container" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false, + "inputHidden": false, + "outputHidden": false, + "trusted": false + }, + "outputs": [], + "source": "%%upload --databaseName RetailDemo --containerName WebsiteData --url https://cosmosnotebooksdata.blob.core.windows.net/notebookdata/websiteData-small.json" + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": "The new database and container should show up under the **Data** section. Use the refresh icon after completing the previous cell. \n\n\"Refresh" + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": "### Run a query using the built-in Azure Cosmos notebook magic\n" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "trusted": false + }, + "outputs": [], + "source": "%%sql\nSELECT c.Action, c.Price as ItemRevenue, c.Country, c.Item FROM c" + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": "We can get more information about the %%sql command using ```%%sql?```" + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": "### Next steps\n\nNow that you've learned how to use basic notebook functionality, follow the **Visualization.ipynb** notebook to further analyze and visualize our data. You can find it under the **Sample Notebooks** section." + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "version": "3.6.8" + }, + "nteract": { + "version": "dataExplorer 1.0" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} \ No newline at end of file diff --git a/test/notebooks/uploadRunAndDeleteNotebook.spec.ts b/test/notebooks/uploadRunAndDeleteNotebook.spec.ts new file mode 100644 index 000000000..dd1628e9c --- /dev/null +++ b/test/notebooks/uploadRunAndDeleteNotebook.spec.ts @@ -0,0 +1,82 @@ +import "expect-puppeteer"; +import { ElementHandle } from "puppeteer"; +import { getTestExplorerFrame } from "./notebookTestUtils"; +import * as path from "path" + +jest.setTimeout(300000); +const NOTEBOOK_OPERATION_DELAY = 2500; +const RENDER_DELAY = 1000; + +describe("sample", () => { + it("portal login", async () => { + const frame = await getTestExplorerFrame(); + + const notebookResourceTree = await frame.waitForSelector(".notebookResourceTree"); + const uploadNotebookPath = "C:/Users/srnara/Downloads/GettingStarted.ipynb"; + const uploadNotebookName = path.basename(uploadNotebookPath); + + const treeNodeHeadersBeforeUpload = await notebookResourceTree.$$(".treeNodeHeader"); + + let ellipses = await treeNodeHeadersBeforeUpload[2].$("button"); + await ellipses.click(); + + await frame.waitFor(RENDER_DELAY); + + let menuItems = await frame.$$(".ms-ContextualMenu-item"); + await menuItems[4].click(); + + const uploadFileButton = await frame.waitForSelector("#importFileButton"); + uploadFileButton.click(); + + const fileChooser = await page.waitForFileChooser(); + fileChooser.accept([uploadNotebookPath]); + + const submitButton = await frame.waitForSelector("#uploadFileButton"); + await submitButton.click(); + + await frame.waitFor(NOTEBOOK_OPERATION_DELAY); + + let uploadedNotebookNode: ElementHandle; + const treeNodeHeadersAfterUpload = await notebookResourceTree.$$(".treeNodeHeader"); + for (var i = 1; i < treeNodeHeadersAfterUpload.length; i++) { + uploadedNotebookNode = treeNodeHeadersAfterUpload[i]; + const nodeLabel = await uploadedNotebookNode.$eval(".nodeLabel", element => element.textContent); + if (nodeLabel === uploadNotebookName) { + break; + } + } + + await uploadedNotebookNode.click(); + await frame.waitForSelector(".tabNavText"); + const tabTitle = await frame.$eval(".tabNavText", element => element.textContent); + expect(tabTitle).toEqual(uploadNotebookName); + + const closeIcon = await frame.waitForSelector(".close-Icon"); + await closeIcon.click(); + + ellipses = await uploadedNotebookNode.$(".treeMenuEllipsis"); + await ellipses.click(); + + await frame.waitFor(RENDER_DELAY); + + menuItems = await frame.$$(".ms-ContextualMenu-item"); + await menuItems[1].click(); + + const deleteAcceptButton = await frame.waitForSelector(".ms-Dialog-action"); + await deleteAcceptButton.click(); + await frame.waitFor(NOTEBOOK_OPERATION_DELAY); + + let index: number; + let deletedNotebookNode: ElementHandle; + const treeNodeHeadersAfterDelete = await notebookResourceTree.$$(".treeNodeHeader"); + for (index = 1; index < treeNodeHeadersAfterDelete.length; index++) { + deletedNotebookNode = treeNodeHeadersAfterDelete[index]; + const nodeLabel = await deletedNotebookNode.$eval(".nodeLabel", element => element.textContent); + if (nodeLabel === uploadNotebookName) { + break; + } + } + + expect(index).toEqual(treeNodeHeadersAfterDelete.length); + }); +}); diff --git a/test/utils/shared.ts b/test/utils/shared.ts index 458899700..dc71e17c1 100644 --- a/test/utils/shared.ts +++ b/test/utils/shared.ts @@ -1,6 +1,8 @@ import crypto from "crypto"; import { Frame } from "puppeteer"; +let testExplorerFrame: Frame; + export async function login(connectionString: string): Promise { const prodUrl = "https://localhost:1234/hostedExplorer.html"; page.goto(prodUrl); diff --git a/webpack.config.js b/webpack.config.js index f2c5cef4d..225287409 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -140,6 +140,11 @@ module.exports = function(env = {}, argv = {}) { template: "src/hostedExplorer.html", chunks: ["hostedExplorer"] }), + new HtmlWebpackPlugin({ + filename: "testExplorer.html", + template: "src/testExplorer.html", + chunks: ["testExplorer"] + }), new HtmlWebpackPlugin({ filename: "Heatmap.html", template: "src/Controls/Heatmap/Heatmap.html", @@ -178,6 +183,7 @@ module.exports = function(env = {}, argv = {}) { index: "./src/Index.ts", quickstart: "./src/quickstart.ts", hostedExplorer: "./src/HostedExplorer.ts", + testExplorer: "./src/TestExplorer.ts", heatmap: "./src/Controls/Heatmap/Heatmap.ts", terminal: "./src/Terminal/index.ts", notebookViewer: "./src/NotebookViewer/NotebookViewer.tsx",