diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index 03fd9ff708..fdf63578a2 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -164,6 +164,8 @@ jobs: needs: install runs-on: ubuntu-latest if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed') + outputs: + static_web_app_url: ${{ steps.builddeploy.outputs.static_web_app_url }} steps: - name: Checkout repository uses: actions/checkout@v3 @@ -187,6 +189,11 @@ jobs: app_location: "/" # App source code path app_artifact_location: "build" # Built app content directory - optional + - name: Set url + run: | + echo "::set-output name=static_web_app_url::$PLAYWRIGHT_TESTS_BASE_URL" + echo $PLAYWRIGHT_TESTS_BASE_URL + close_pull_request_job: if: github.event_name == 'pull_request' && github.event.action == 'closed' runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index c35c3ecb30..7455e5cffe 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,5 @@ yarn-error.log* .idea .vs *.xml +playwright-report/index.html +test-results diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 4bd6213939..49499e2c5e 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -18,7 +18,9 @@ "ms-vscode.sublime-keybindings", "redhat.vscode-yaml", "redhat.vscode-commons", - "eamodio.gitlens" + "eamodio.gitlens", + "ms-playwright.playwright", + "nitayneeman.playwright-snippets" ], // List of extensions recommended by VS Code that should not be recommended for users of this workspace. "unwantedRecommendations": [ diff --git a/README.md b/README.md index a15e154bd6..06b7fb2340 100644 --- a/README.md +++ b/README.md @@ -1,31 +1,31 @@ # Microsoft Graph Explorer V4 + [![Build Status](https://dev.azure.com/japhethobalak/japhethobalak/_apis/build/status/microsoftgraph.microsoft-graph-explorer-v2?branchName=dev)](https://dev.azure.com/japhethobalak/japhethobalak/_build/latest?definitionId=4&branchName=dev) The [Microsoft Graph Explorer V4](https://developer.microsoft.com/graph/graph-explorer) lets developers quickly navigate and test API endpoints. The Graph Explorer is written in [TypeScript](https://www.typescriptlang.org/) and powered by: -* [React](https://reactjs.org/) -* [Office Fabric](https://dev.office.com/fabric) +- [React](https://reactjs.org/) +- [Office Fabric](https://dev.office.com/fabric) ## Running the explorer locally -* `npm install` to install project dependencies. `npm` is installed by default with [Node.js](https://nodejs.org/). -* `npm start` starts the TypeScript compiler in watch mode and the local server. It should open your browser automatically with the Graph Explorer at [http://localhost:3000/](http://localhost:3000). +- `npm install` to install project dependencies. `npm` is installed by default with [Node.js](https://nodejs.org/). +- `npm start` starts the TypeScript compiler in watch mode and the local server. It should open your browser automatically with the Graph Explorer at [http://localhost:3000/](http://localhost:3000). + +### Enabling authentication with your own credentials -#### Enabling authentication with your own credentials -* Sign in to your Microsoft account (or Create one) at the [Microsoft Azure Portal](https://ms.portal.azure.com/). -* Find the Azure service named App registrations. If you haven't used this service before, you might need to search for it in the search bar. -* In the App registrations page, click `+ New registration`. You will be redirected to a form in the Microsoft Azure portal where you Register an application. Fill out the form and set the Redirect URI to a `Single-page application (SPA)` with `http://localhost:3000`. You can also set it from authentication tab in the app you have just created. -* Create a `.env` file at the root of the project/repo and add the following keys. - - REACT_APP_CLIENT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - - REACT_APP_INSTRUMENTATION_KEY=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -Where `REACT_APP_CLIENT_ID` is the `Application (client) ID` from the Azure portal and `REACT_APP_INSTRUMENTATION_KEY` is the `Object ID` from the portal. +- Sign in to your Microsoft account (or Create one) at the [Microsoft Azure Portal](https://ms.portal.azure.com/). +- Find the Azure service named App registrations. If you haven't used this service before, you might need to search for it in the search bar. +- In the App registrations page, click `+ New registration`. You will be redirected to a form in the Microsoft Azure portal where you Register an application. Fill out the form and set the Redirect URI to a `Single-page application (SPA)` with `http://localhost:3000`. You can also set it from authentication tab in the app you have just created. +- Create a `.env` file at the root of the project/repo and add the following keys. - REACT_APP_CLIENT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - REACT_APP_INSTRUMENTATION_KEY=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + Where `REACT_APP_CLIENT_ID` is the `Application (client) ID` from the Azure portal and `REACT_APP_INSTRUMENTATION_KEY` is the `Object ID` from the portal. ## Other commands -* `npm test` to run tests from the command line for scenarios like parsing metadata and functional explorer tests. -* `npm run ci` to run accessibility tests from the command line -* `npm run lint` linting your files + +- `npm test` to run tests from the command line for scenarios like parsing metadata and functional explorer tests. +- `npm run lint` linting your files ## Getting Help & Guides ### Where To Get Support @@ -46,26 +46,34 @@ Are you new to Graph Explorer or would like to raise a bug or request a feature? * Refer to [Microsoft Graph Quick Start](https://developer.microsoft.com/en-us/graph/quick-start) to get a pre-initialized SDK sample application up and running in less 3 minutes using the language of your choice. ## Contributing + Please see the [contributing guidelines](CONTRIBUTING.md). This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. -## Testing Accessbility -* Download the latest stable chromedriver from [here](https://chromedriver.chromium.org/). -* In your `.env` file, create a variable `REACT_APP_CHROMEDRIVER_PATH` and save the path to your `chromedriver.exe` file. - For example (on a Windows PC) it would be : `REACT_APP_CHROMEDRIVER_PATH=C:\\SeleniumWebDrivers\\ChromeDriver\\chromedriver.exe` - Take note of the format. -* Save your changes. -* On your terminal run the command `npm install`. -* Once the installation is complete run the command `npm run ci`. +## E2E playwright testing + +- Playwright requires a running GE Url to run against. +- In your `.env` file, create add variables: + - PLAYWRIGHT_TESTS_USERNAME='your demo tenant email address' + - PLAYWRIGHT_TESTS_PASSWORD='password to the demo tenant account' + - PLAYWRIGHT_TESTS_BASE_URL='url that you are running against' // http://localhost:3000 if testing locally +- Save your changes. +- On your terminal run the command `npx playwright install` +- On your terminal run the command `npx playwright install-deps`. +- Once the installation is complete run the command `npx playwright test ui`. +- Playwright commands can be extended using arguments described in the official documentation [Running tests](https://playwright.dev/docs/running-tests) ## Known issues -* You cannot remove permissions by using the Graph Explorer UI. You will need to [remove the application consent](http://shawntabrizi.com/aad/revoking-consent-azure-active-directory-applications/) and then re-consent to remove permissions. I know, this is far from a good experience. + +- You cannot remove permissions by using the Graph Explorer UI. You will need to [remove the application consent](http://shawntabrizi.com/aad/revoking-consent-azure-active-directory-applications/) and then re-consent to remove permissions. I know, this is far from a good experience. ## Additional resources -* [Microsoft Graph website](https://graph.microsoft.io) -* [Office Dev Center](http://dev.office.com/) -* [Graph Explorer releases](https://github.com/microsoftgraph/microsoft-graph-explorer/releases) + +- [Microsoft Graph website](https://graph.microsoft.io) +- [Office Dev Center](http://dev.office.com/) +- [Graph Explorer releases](https://github.com/microsoftgraph/microsoft-graph-explorer/releases) ## Copyright + Copyright (c) 2017 Microsoft. All rights reserved. diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 2d7880f385..2a49b03f94 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -32,6 +32,10 @@ pr: - azure-pipelines.yml - package-lock.json +variables: + isMaster: $[eq(variables['Build.SourceBranch'], 'refs/heads/master')] + isDev: $[eq(variables['Build.SourceBranch'], 'refs/heads/dev')] + trigger: branches: include: @@ -86,10 +90,6 @@ jobs: npm test displayName: "Runs Unit tests" - - script: | - npm run ci - displayName: "Runs Accessibility tests" - - task: PublishTestResults@2 condition: succeededOrFailed() inputs: @@ -102,9 +102,58 @@ jobs: displayName: "Run build" - job: Two + displayName: "Run playwright tests" + condition: eq(variables['isDev'], 'true') + steps: + - task: NodeTool@0 + inputs: + versionSpec: "14.20.x" + displayName: "Install npm" + + - script: | + npm install + displayName: "npm install" + + - script: | + npm install -D @playwright/test + npx playwright install-deps + displayName: "Install playwright dependancies" + + - script: | + npx playwright install + displayName: "Install playwright" + + - script: | + set CI=true + npm run test-playwright + + env: + REACT_APP_CLIENT_ID: $(REACT_APP_PLAYWRIGHT_TEST_CLIENT_ID) + REACT_APP_INSTRUMENTATION_KEY: $(REACT_APP_STAGING_INSTRUMENTATION_KEY) + REACT_APP_FEEDBACK_CAMPAIGN_ID: $(REACT_APP_STAGING_FEEDBACK_CAMPAIGN_ID) + REACT_APP_NPS_FEEDBACK_CAMPAIGN_ID: $(REACT_APP_NPS_FEEDBACK_CAMPAIGN_ID) + REACT_APP_NOMINATION_PERIOD: $(REACT_APP_NOMINATION_PERIOD) + REACT_APP_COOLDOWN_PERIOD: $(REACT_APP_COOLDOWN_PERIOD) + REACT_APP_USAGE_TIME: $(REACT_APP_USAGE_TIME) + PLAYWRIGHT_TESTS_BASE_URL: $(PLAYWRIGHT_TESTS_BASE_URL) + PLAYWRIGHT_TESTS_USERNAME: $(PLAYWRIGHT_TESTS_USERNAME) + PLAYWRIGHT_TESTS_PASSWORD: $(PLAYWRIGHT_TESTS_PASSWORD) + displayName: "Run playwright tests" + + - script: | + npm run test-playwright-accessibility + displayName: "Run accessibility tests" + + - publish: $(System.DefaultWorkingDirectory)/playwright-report + artifact: playwright-report + condition: always() + displayName: "Publish test results" + + + - job: Three displayName: "Publish artifacts" dependsOn: One - condition: succeeded() + condition: and(succeeded(), or(eq(variables['isMaster'], 'true'), eq(variables['isDev'], 'true'))) steps: - task: NodeTool@0 inputs: @@ -129,7 +178,7 @@ jobs: - task: PowerShell@2 displayName: "Set version-number" - condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/master')) + condition: and(succeeded(), eq(variables['isMaster'], 'true')) inputs: targetType: "inline" script: | @@ -141,7 +190,7 @@ jobs: - script: | npm run build - condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/master')) + condition: and(succeeded(), eq(variables['isMaster'], 'true')) env: REACT_APP_CLIENT_ID: $(REACT_APP_PROD_CLIENT_ID) REACT_APP_INSTRUMENTATION_KEY: $(REACT_APP_INSTRUMENTATION_KEY) diff --git a/jest.config.js b/jest.config.js index 7a59208d88..59a79a86e7 100644 --- a/jest.config.js +++ b/jest.config.js @@ -6,7 +6,6 @@ module.exports = { '!build/**', '!src/**/*.d.ts', '!src/index.tsx', - '!src/tests/accessibility/**', '!src/app/middleware/telemetryMiddleware.ts', '!src/telemetry/telemetry.ts' ], diff --git a/package-lock.json b/package-lock.json index 945e4a6ebb..cc8584b546 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,6 +27,15 @@ "version": "file:packages/types-core-2.16.189.tgz", "integrity": "sha512-28Y+BPVqjDXsT8AMUXaAxU8U91sgbuw/yHtGjfTzkn+3Qrg4JpOYLp+hkULpLpskZSmwv8CWM7g5Uu6ueYMydA==" }, + "@axe-core/playwright": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/@axe-core/playwright/-/playwright-4.4.5.tgz", + "integrity": "sha512-oyh8TuAjPc6GIut3E+BiJU19jAEuzhf1ZMB7nrJqfGWsU6kWP0ymRwuj6TX3JJTT5mL3m+yFhph5RhCr/MkQ1g==", + "dev": true, + "requires": { + "axe-core": "^4.4.3" + } + }, "@axe-core/webdriverjs": { "version": "4.4.5", "resolved": "https://registry.npmjs.org/@axe-core/webdriverjs/-/webdriverjs-4.4.5.tgz", @@ -4466,6 +4475,24 @@ "fastq": "^1.6.0" } }, + "@playwright/test": { + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.29.2.tgz", + "integrity": "sha512-+3/GPwOgcoF0xLz/opTnahel1/y42PdcgZ4hs+BZGIUjtmEFSXGg+nFoaH3NSmuc7a6GSFwXDJ5L7VXpqzigNg==", + "dev": true, + "requires": { + "@types/node": "*", + "playwright-core": "1.29.2" + }, + "dependencies": { + "playwright-core": { + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.29.2.tgz", + "integrity": "sha512-94QXm4PMgFoHAhlCuoWyaBYKb92yOcGVHdQLoxQ7Wjlc7Flg4aC/jbFW7xMR52OfXMVkWicue4WXE7QEegbIRA==", + "dev": true + } + } + }, "@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -4581,111 +4608,12 @@ "integrity": "sha512-g697J3WxV/Zytemz8aTuKjTGYtta9+02kva3C1xc7KXB8GdbfE1akGJIsZLyY/FSh2QrnE+fiB7vmWU3XNcb6A==", "dev": true }, - "@testing-library/dom": { - "version": "8.19.1", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.19.1.tgz", - "integrity": "sha512-P6iIPyYQ+qH8CvGauAqanhVnjrnRe0IZFSYCeGkSRW9q3u8bdVn2NPI+lasFyVsEQn1J/IFmp5Aax41+dAP9wg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/runtime": "^7.12.5", - "@types/aria-query": "^5.0.1", - "aria-query": "^5.0.0", - "chalk": "^4.1.0", - "dom-accessibility-api": "^0.5.9", - "lz-string": "^1.4.4", - "pretty-format": "^27.0.2" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "aria-query": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", - "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", - "dev": true, - "requires": { - "deep-equal": "^2.0.5" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "@testing-library/react": { - "version": "13.4.0", - "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-13.4.0.tgz", - "integrity": "sha512-sXOGON+WNTh3MLE9rve97ftaZukN3oNf2KjDy7YTx6hcTO2uuLHuCGynMDhFwGw/jYf4OJ2Qk0i4i79qMNNkyw==", - "dev": true, - "requires": { - "@babel/runtime": "^7.12.5", - "@testing-library/dom": "^8.5.0", - "@types/react-dom": "^18.0.0" - } - }, - "@testing-library/user-event": { - "version": "14.4.3", - "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.4.3.tgz", - "integrity": "sha512-kCUc5MEwaEMakkO5x7aoD+DLi02ehmEM2QCGWvNqAS1dV/fAvORWEjnjsEIvml59M7Y5kCkWN6fCCyPOe8OL6Q==", - "dev": true - }, "@tootallnate/once": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", "dev": true }, - "@types/aria-query": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.1.tgz", - "integrity": "sha512-XTIieEY+gvJ39ChLcB4If5zHtPxt3Syj5rgZR+e1ctpmK8NjPf0zFqsz4JpLJT0xla9GFDKjy8Cpu331nrmE1Q==", - "dev": true - }, "@types/atob-lite": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@types/atob-lite/-/atob-lite-2.0.0.tgz", @@ -6533,10 +6461,10 @@ } } }, - "available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "axe-core": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.6.2.tgz", + "integrity": "sha512-b1WlTV8+XKLj9gZy2DZXgQiyDp9xkkoe2a6U6UbYccScq2wgH/YwCeI2/Jq2mgo0HzQxqJOjWZBLeA/mqsk5Mg==", "dev": true }, "axios": { @@ -7525,60 +7453,6 @@ "integrity": "sha1-wB3mPvsO7JeYgB1Ax+Da4ltYLIQ=", "dev": true }, - "deep-equal": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.1.0.tgz", - "integrity": "sha512-2pxgvWu3Alv1PoWEyVg7HS8YhGlUFUV7N5oOvfL6d+7xAmLSemMwv/c8Zv/i9KFzxV5Kt5CAvQc70fLwVuf4UA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "es-get-iterator": "^1.1.2", - "get-intrinsic": "^1.1.3", - "is-arguments": "^1.1.1", - "is-date-object": "^1.0.5", - "is-regex": "^1.1.4", - "isarray": "^2.0.5", - "object-is": "^1.1.5", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.4.3", - "side-channel": "^1.0.4", - "which-boxed-primitive": "^1.0.2", - "which-collection": "^1.0.1", - "which-typed-array": "^1.1.8" - }, - "dependencies": { - "get-intrinsic": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", - "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - } - }, - "isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true - }, - "object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - } - } - } - }, "deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -7707,12 +7581,6 @@ "esutils": "^2.0.2" } }, - "dom-accessibility-api": { - "version": "0.5.15", - "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.15.tgz", - "integrity": "sha512-8o+oVqLQZoruQPYy3uAAQtc6YbtSiRq5aPJBhJ82YTJRHvI6ofhYAkC81WmjFTnfUbqg6T3aCglIpU9p/5e7Cw==", - "dev": true - }, "dom-converter": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", @@ -8031,30 +7899,6 @@ "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", "dev": true }, - "es-get-iterator": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.2.tgz", - "integrity": "sha512-+DTO8GYwbMCwbywjimwZMHp8AuYXOS2JZFWoi2AlPOS3ebnII9w/NLpNZtA7A0YLaVDw+O7KFCeoIV7OPvM7hQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.0", - "has-symbols": "^1.0.1", - "is-arguments": "^1.1.0", - "is-map": "^2.0.2", - "is-set": "^2.0.2", - "is-string": "^1.0.5", - "isarray": "^2.0.5" - }, - "dependencies": { - "isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true - } - } - }, "es-module-lexer": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", @@ -9558,15 +9402,6 @@ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.0.tgz", "integrity": "sha512-aExlJShTV4qOUOL7yF1U5tvLCB0xQuudbf6toyYA0E/acBNw71mvjFTnLaRp50aQaYocMR0a/RMMBIHeZnGyjQ==" }, - "for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "requires": { - "is-callable": "^1.1.3" - } - }, "fork-ts-checker-webpack-plugin": { "version": "7.2.14", "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-7.2.14.tgz", @@ -10298,16 +10133,6 @@ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" }, - "is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -10389,12 +10214,6 @@ "is-extglob": "^2.1.1" } }, - "is-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", - "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==", - "dev": true - }, "is-module": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", @@ -10460,12 +10279,6 @@ "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==", "dev": true }, - "is-set": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", - "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==", - "dev": true - }, "is-shared-array-buffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", @@ -10501,31 +10314,12 @@ "has-symbols": "^1.0.2" } }, - "is-typed-array": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", - "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", - "dev": true, - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" - } - }, "is-url": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==", "dev": true }, - "is-weakmap": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", - "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==", - "dev": true - }, "is-weakref": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", @@ -10534,16 +10328,6 @@ "call-bind": "^1.0.2" } }, - "is-weakset": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz", - "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - } - }, "is-wsl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", @@ -13904,9 +13688,9 @@ } }, "joi": { - "version": "17.6.0", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.6.0.tgz", - "integrity": "sha512-OX5dG6DTbcr/kbMFj0KGYxuew69HPcAE3K/sZpEV2nP6e/j/C0HV+HNiBPCASxdx5T7DMoa0s8UeHWMnb6n2zw==", + "version": "17.7.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.7.0.tgz", + "integrity": "sha512-1/ugc8djfn93rTE3WRKdCzGGt/EtiYKxITMO4Wiv6q5JL1gl9ePt4kBsl1S499nbosspfctIQTpYIhSmHA3WAg==", "dev": true, "requires": { "@hapi/hoek": "^9.0.0", @@ -14286,12 +14070,6 @@ "yallist": "^3.0.2" } }, - "lz-string": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz", - "integrity": "sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=", - "dev": true - }, "magic-string": { "version": "0.25.9", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", @@ -16362,9 +16140,9 @@ } }, "rxjs": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz", - "integrity": "sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.6.0.tgz", + "integrity": "sha512-DDa7d8TFNUalGC9VqXvQ1euWNN7sc63TrUCuM9J998+ViviahMIjKSOU7rfcgFOF+FCD71BhDRv4hrFz+ImDLQ==", "dev": true, "requires": { "tslib": "^2.1.0" @@ -17947,32 +17725,6 @@ "is-symbol": "^1.0.3" } }, - "which-collection": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz", - "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==", - "dev": true, - "requires": { - "is-map": "^2.0.1", - "is-set": "^2.0.1", - "is-weakmap": "^2.0.1", - "is-weakset": "^2.0.1" - } - }, - "which-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", - "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", - "dev": true, - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.10" - } - }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", diff --git a/package.json b/package.json index 55b82af365..3119724416 100644 --- a/package.json +++ b/package.json @@ -68,15 +68,18 @@ "scripts": { "start": "node scripts/start.js", "build": "node scripts/build.js && node versioned-build.js", - "test": "node scripts/test.js --no-watch --testPathIgnorePatterns=src/tests/accessibility /scripts/ --max-old-space-size=8192", + "test": "node scripts/test.js --no-watch --testPathIgnorePatterns=src/tests/ui src/tests/accessibility /scripts/ --max-old-space-size=8192", "lint": "eslint . \"**/*.{js,ts,tsx}\"", - "start-server": "npm start", - "ci": "start-server-and-test start-server http://localhost:3000 test-ci", - "test-ci": "node scripts/test.js --no-watch accessibility.spec.ts", "prebuild:prod": "standard-version", "build:prod": "npm run build", "bump": "standard-version --skip.tag --skip.changelog", - "preinstall": "npx npm-force-resolutions" + "preinstall": "npx npm-force-resolutions", + "start-server": "npm start", + "test-playwright": "start-server-and-test start-server http://localhost:3000 test-ui", + "test-ui": "npx playwright test src/tests/ui/", + "test-playwright-accessibility": "start-server-and-test start-server http://localhost:3000 test-accessibility", + "test-accessibility": "npx playwright test src/tests/accessibility" + }, "eslintConfig": { "extends": "react-app" @@ -88,8 +91,8 @@ "not op_mini all" ], "devDependencies": { - "@testing-library/react": "13.4.0", - "@testing-library/user-event": "14.4.3", + "@axe-core/playwright": "4.4.5", + "@playwright/test": "1.29.2", "@types/chromedriver": "81.0.1", "@types/enzyme": "3.10.12", "@types/enzyme-adapter-react-16": "1.0.6", diff --git a/playwright.config.ts b/playwright.config.ts new file mode 100644 index 0000000000..6ed5e38c08 --- /dev/null +++ b/playwright.config.ts @@ -0,0 +1,31 @@ +require('dotenv').config(); +import type { PlaywrightTestConfig } from '@playwright/test'; + +const baseURL = process.env.PLAYWRIGHT_TESTS_BASE_URL!; + +const config: PlaywrightTestConfig = { + globalSetup: require.resolve('./src/tests/ui/global-setup'), + expect: { + toMatchSnapshot: { + threshold: 0.3, + maxDiffPixelRatio: 0.01 + } + }, + use: { + baseURL, + trace: 'on-first-retry', + headless: !!process.env.CI, + ignoreHTTPSErrors: true, + screenshot: 'only-on-failure' + }, + testDir: './src/tests', + reporter: [ + [ + 'html', + { outputFolder: 'playwright-report' } + ] + ], + retries: 1, + timeout: 60000 +}; +export default config; \ No newline at end of file diff --git a/src/app/views/sidebar/sample-queries/SampleQueries.tsx b/src/app/views/sidebar/sample-queries/SampleQueries.tsx index 43fb30db9b..1718b71179 100644 --- a/src/app/views/sidebar/sample-queries/SampleQueries.tsx +++ b/src/app/views/sidebar/sample-queries/SampleQueries.tsx @@ -138,6 +138,7 @@ const UnstyledSampleQueries = (sampleProps?: ISampleQueriesProps): JSX.Element = calloutProps={{ gapSpace: 0 }} > trackDocumentLinkClickedEvent(item)} diff --git a/src/tests/accessibility/accessibility.spec.ts b/src/tests/accessibility/accessibility.spec.ts index 3f42f76a94..a722250dfa 100644 --- a/src/tests/accessibility/accessibility.spec.ts +++ b/src/tests/accessibility/accessibility.spec.ts @@ -1,40 +1,22 @@ -import AxeBuilder from '@axe-core/webdriverjs'; -import webdriver, { ThenableWebDriver } from 'selenium-webdriver'; -import chrome from 'selenium-webdriver/chrome'; +import AxeBuilder from '@axe-core/playwright'; +import { test, expect, Page } from '@playwright/test'; -const TEST_TIMEOUT_MS = 500000; // in milliseconds = 5min +let page: Page; -describe('Graph Explorer accessibility', () => { - let driver: ThenableWebDriver; - jest.setTimeout(TEST_TIMEOUT_MS); - - // set browser environment to use headless Chrome - beforeAll(async () => { - - driver = new webdriver.Builder() - .forBrowser('chrome') - .setChromeOptions(new chrome.Options().headless()) - .withCapabilities(webdriver.Capabilities.chrome()) - .build(); - }, TEST_TIMEOUT_MS); +test.beforeAll(async ({ browser }) => { + const context = await browser.newContext(); + page = await context.newPage(); + await page.goto('/'); +}); - // end browser environment - afterAll(async () => { - return driver && driver.quit(); - }, TEST_TIMEOUT_MS); +test.describe('Accessibility', () => { + test.use({ viewport: { width: 1024, height: 768 }}); - // load the page where app is hosted - beforeEach(async () => { - await driver - .manage() - .setTimeouts({ implicit: 0, pageLoad: 60000, script: TEST_TIMEOUT_MS }); - await driver.get('http://localhost:3000/'); - }, TEST_TIMEOUT_MS); + test('should not have any automatically detectable accessibility issues', async () => { - // scan the page and return an analysis - it('checks for accessibility violations', async () => { - const accessibilityScanResults = await new AxeBuilder(driver) - // disabled as main landmark already exists on live site + await page.locator('[aria-label="Settings"]').isVisible(); + const accessibilityScan = new AxeBuilder({ page }).setLegacyMode(); + const result = await accessibilityScan .disableRules([ 'landmark-one-main', 'region', @@ -42,9 +24,12 @@ describe('Graph Explorer accessibility', () => { 'html-has-lang', 'page-has-heading-one', 'landmark-unique', + 'aria-allowed-attr', 'aria-required-children' ]) .analyze(); - expect(accessibilityScanResults.violations).toStrictEqual([]); + accessibilityScan.setLegacyMode(false); + + expect(result.violations).toEqual([]); }); -}); +}) \ No newline at end of file diff --git a/src/tests/ui/anonymous-experiences/header.spec.ts b/src/tests/ui/anonymous-experiences/header.spec.ts new file mode 100644 index 0000000000..4e6d4f7ecf --- /dev/null +++ b/src/tests/ui/anonymous-experiences/header.spec.ts @@ -0,0 +1,119 @@ +/* eslint-disable max-len */ +import { test, expect, Page } from '@playwright/test'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); + await page.goto('/'); +}); + +// await expect(authenticatedPage).toHaveScreenshot('runQuery.png', { clip: { x: 0, y: 0, width: 1920, height: 400 } }); + +test.describe('Settings button', () => { + test('should change theme settings', async () => { + + const settingsButton = page.locator('[aria-label="Settings"]'); + await settingsButton.click(); + const changeThemeButton = page.locator('button[role="menuitem"]:has-text("Change theme")'); + await changeThemeButton.click(); + await page.evaluate(() => document.fonts.ready); + await page.waitForTimeout(200); + expect(await page.screenshot({ clip: { x: 300, y: 0, width: 1920, height: 1080 } })).toMatchSnapshot(); + await page.locator('text=Dark').click(); + const closeThemeDialogButton = page.locator('button:has-text("Close")'); + await closeThemeDialogButton.click(); + await page.locator('[aria-label="Settings"]').click(); + await changeThemeButton.click(); + await page.locator('text=High contrast').click(); + await page.evaluate(() => document.fonts.ready); + await page.waitForTimeout(200); + expect(await page.screenshot({ clip: { x: 300, y: 0, width: 1920, height: 1080 } })).toMatchSnapshot(); + await closeThemeDialogButton.click(); + await settingsButton.click(); + await changeThemeButton.click(); + await page.locator('text=Light').click(); + await page.evaluate(() => document.fonts.ready); + await page.waitForTimeout(200); + expect(await page.screenshot({ clip: { x: 300, y: 0, width: 1920, height: 1080 } })).toMatchSnapshot(); + await page.locator('text=Close').click(); + }); + + test('should get a sandbox with sample data', async () => { + test.slow(); + await page.locator('[aria-label="Settings"]').click(); + await page.evaluate(() => document.fonts.ready); + await page.waitForTimeout(700); + const [page1] = await Promise.all([ + page.waitForEvent('popup'), + page.locator('text=Get a sandbox with sample data').click() + ]); + expect(page1.url()).toBe('https://developer.microsoft.com/en-US/microsoft-365/dev-program'); + }) +}) + +test.describe('Help button', () => { + test('should open the relevant help sites',async () => { + await page.locator('[aria-label="Help"]').click(); + const [page1] = await Promise.all([ + page.waitForEvent('popup'), + page.locator('text=Report an Issue').click() + ]); + + expect(page1.url().indexOf('https://github.com/login')).toBeGreaterThan(-1); + await page.locator('[aria-label="Help"]').click(); + const [page2] = await Promise.all([ + page.waitForEvent('popup'), + page.locator('text=Get started with Graph Explorer').click() + ]); + expect(page2.url().indexOf('https://learn.microsoft.com/en-us/graph/graph-explorer')).toBeGreaterThan(-1); + + await page.locator('[aria-label="Help"]').click(); + const [page3] = await Promise.all([ + page.waitForEvent('popup'), + page.locator('ul[role="presentation"] >> text=Microsoft Graph API Reference').click() + ]); + expect(page3.url().indexOf('https://learn.microsoft.com/en-us/graph/api')).toBeGreaterThan(-1); + + await page.locator('[aria-label="Help"]').click(); + const [page4] = await Promise.all([ + page.waitForEvent('popup'), + page.locator('text=GitHub').click() + ]); + expect(page4.url().indexOf('https://github.com/microsoftgraph/microsoft-graph-explorer')).toBeGreaterThan(-1); + }) +}) + +test.describe('Feedback button', () => { + test('should provide feedback', async () => { + await page.locator('[aria-label="Help Improve Graph Explorer\\?"]').click(); + await page.evaluate(() => document.fonts.ready); + await page.waitForTimeout(200); + expect(await page.screenshot({ clip: { x: 300, y: 0, width: 1920, height: 1080 } })).toMatchSnapshot(); + await page.locator('.obf-ChoiceGroupIcon').first().click(); + await page.locator('[aria-label="Tell us more about your experience"]').click(); + await page.locator('[aria-label="Tell us more about your experience"]').fill('Ge is just so simple to use'); + await page.locator('input[type="checkbox"]').check(); + await page.locator('[placeholder="Email \\(optional\\)"]').click(); + await page.locator('[placeholder="Email \\(optional\\)"]').fill(' dummyemail@email.com'); + await page.evaluate(() => document.fonts.ready); + await page.waitForTimeout(200); + expect(await page.screenshot()).toMatchSnapshot(); + await page.locator('text=Submit').click(); + const response = page.locator('text=Graph Explorer Feedback - Submitted Successfully'); + await page.evaluate(() => document.fonts.ready); + await page.waitForTimeout(200); + expect(await page.screenshot({ clip: { x: 300, y: 0, width: 1920, height: 1080 } })).toMatchSnapshot(); + expect(await response.isVisible()).toBeTruthy(); + }) +}) + +test.describe('Sign in button', () => { + test('should launch the sign in popup', async () => { + const [page2] = await Promise.all([ + page.waitForEvent('popup'), + page.locator('[aria-label="Sign in"]').click() + ]); + expect(page2).toBeDefined(); + }) +}) \ No newline at end of file diff --git a/src/tests/ui/anonymous-experiences/header.spec.ts-snapshots/Feedback-button-should-provide-feedback-1-win32.png b/src/tests/ui/anonymous-experiences/header.spec.ts-snapshots/Feedback-button-should-provide-feedback-1-win32.png new file mode 100644 index 0000000000..0f379684d3 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/header.spec.ts-snapshots/Feedback-button-should-provide-feedback-1-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/header.spec.ts-snapshots/Feedback-button-should-provide-feedback-2-win32.png b/src/tests/ui/anonymous-experiences/header.spec.ts-snapshots/Feedback-button-should-provide-feedback-2-win32.png new file mode 100644 index 0000000000..8733ed70e2 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/header.spec.ts-snapshots/Feedback-button-should-provide-feedback-2-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/header.spec.ts-snapshots/Feedback-button-should-provide-feedback-3-win32.png b/src/tests/ui/anonymous-experiences/header.spec.ts-snapshots/Feedback-button-should-provide-feedback-3-win32.png new file mode 100644 index 0000000000..02e9ad6648 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/header.spec.ts-snapshots/Feedback-button-should-provide-feedback-3-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/header.spec.ts-snapshots/Settings-button-should-change-theme-settings-1-win32.png b/src/tests/ui/anonymous-experiences/header.spec.ts-snapshots/Settings-button-should-change-theme-settings-1-win32.png new file mode 100644 index 0000000000..583985b019 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/header.spec.ts-snapshots/Settings-button-should-change-theme-settings-1-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/header.spec.ts-snapshots/Settings-button-should-change-theme-settings-2-win32.png b/src/tests/ui/anonymous-experiences/header.spec.ts-snapshots/Settings-button-should-change-theme-settings-2-win32.png new file mode 100644 index 0000000000..c386bb5ca6 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/header.spec.ts-snapshots/Settings-button-should-change-theme-settings-2-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/header.spec.ts-snapshots/Settings-button-should-change-theme-settings-3-win32.png b/src/tests/ui/anonymous-experiences/header.spec.ts-snapshots/Settings-button-should-change-theme-settings-3-win32.png new file mode 100644 index 0000000000..36b751b8a6 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/header.spec.ts-snapshots/Settings-button-should-change-theme-settings-3-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/request.spec.ts b/src/tests/ui/anonymous-experiences/request.spec.ts new file mode 100644 index 0000000000..b386004a0a --- /dev/null +++ b/src/tests/ui/anonymous-experiences/request.spec.ts @@ -0,0 +1,198 @@ +/* eslint-disable max-len */ +import { test, expect, Page } from '@playwright/test'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); + await page.goto('/'); +}); + +test.describe('Run query', () => { + + test('should change version options', async () => { + await page.locator('[aria-label="HTTP request method option"] >> text=GET').click(); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot({ clip: { x: 300, y: 0, width: 1920, height: 1080 } })).toMatchSnapshot(); + await page.locator('button[role="option"]:has-text("POST")').click(); + await page.locator('[aria-label="HTTP request method option"] >> text=POST').click(); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot({ clip: { x: 300, y: 0, width: 1920, height: 1080 } })).toMatchSnapshot(); + await page.locator('button[role="option"]:has-text("PUT")').click(); + await page.locator('[aria-label="HTTP request method option"] >> text=PUT').click(); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot({ clip: { x: 300, y: 0, width: 1920, height: 1080 } })).toMatchSnapshot(); + await page.locator('button[role="option"]:has-text("PATCH")').click(); + await page.locator('[aria-label="HTTP request method option"] >> text=PATCH').click(); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot({ clip: { x: 300, y: 0, width: 1920, height: 1080 } })).toMatchSnapshot(); + await page.locator('button[role="option"]:has-text("DELETE")').click(); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot({ clip: { x: 300, y: 0, width: 1920, height: 1080 } })).toMatchSnapshot(); + expect(page.locator('text=Sign in to use this method')).toBeDefined(); + }) + + test('Changing the version via the dropdown menu changes the version in the request URL field', async () => { + await page.locator('[aria-label="Microsoft Graph API Version option"] span:has-text("v1.0")').click(); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot({ clip: { x: 300, y: 0, width: 1920, height: 1080 } })).toMatchSnapshot(); + await page.locator('button[role="option"]:has-text("beta")').click(); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot({ clip: { x: 300, y: 0, width: 1920, height: 1080 } })).toMatchSnapshot(); + expect('input[aria-label="Query sample input"]:has-text("https://graph.microsoft.com/beta/me")').toBeDefined() + + await page.locator('[aria-label="Microsoft Graph API Version option"] span:has-text("beta")').click(); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot({ clip: { x: 300, y: 0, width: 1920, height: 1080 } })).toMatchSnapshot(); + await page.locator('button[role="option"]:has-text("v1.0")').click(); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot({ clip: { x: 300, y: 0, width: 1920, height: 1080 } })).toMatchSnapshot(); + expect('input[aria-label="Query sample input"]:has-text("https://graph.microsoft.com/v1.0/me")').toBeDefined() + + }); + + test('Changing the version via the request URL field changes the version in the dropdown', async () => { + await page.locator('[aria-label="Query sample input"]').fill('https://graph.microsoft.com/beta/me'); + expect('[aria-label="Microsoft Graph API Version option"] span:has-text("beta")').toBeDefined(); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot({ clip: { x: 300, y: 0, width: 1920, height: 1080 } })).toMatchSnapshot(); + + await page.locator('[aria-label="Query sample input"]').fill('https://graph.microsoft.com/v1.0/me'); + expect('[aria-label="Microsoft Graph API Version option"] span:has-text("v1.0")').toBeDefined(); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot({ clip: { x: 300, y: 0, width: 1920, height: 1080 } })).toMatchSnapshot(); + + }); + + test('Adds message and gets autocomplete options', async () => { + + const queryInputField = page.locator('[aria-label="Query sample input"]'); + await queryInputField.click(); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot({ clip: { x: 300, y: 0, width: 1920, height: 1080 } })).toMatchSnapshot(); + + await queryInputField.type('/mess'); + await page.locator('label:has-text("messages")').click(); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot({ clip: { x: 300, y: 0, width: 1920, height: 1080 } })).toMatchSnapshot(); + await queryInputField.type('?sel'); + await page.locator('label:has-text("$select")').click(); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot({ clip: { x: 300, y: 0, width: 1920, height: 1080 } })).toMatchSnapshot(); + await queryInputField.press('Tab'); + await queryInputField.press('Tab'); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot({ clip: { x: 300, y: 0, width: 1920, height: 1080 } })).toMatchSnapshot(); + + // eslint-disable-next-line max-len + expect('input[aria-label="Query sample input"]:has-text("https://graph.microsoft.com/v1.0/me/messages?$select=id")').toBeDefined() + }); + + test('user can run query', async () => { + const profileSample = page.locator('[aria-label="my profile"]'); + await profileSample.click(); + await page.evaluate(() => document.fonts.ready); + await page.waitForTimeout(200); + const runQueryButton = page.locator('.run-query-button button'); + expect(await page.screenshot()).toMatchSnapshot(); + await runQueryButton.click(); + await page.waitForTimeout(100); + await page.evaluate(() => document.fonts.ready); + const messageBar = page.locator('.ms-MessageBar-content'); + expect(await page.screenshot()).toMatchSnapshot(); + expect(messageBar).toBeDefined(); + }); + + test('should show documentation link for queries with links ', async () => { + await page.locator('[aria-label="my profile"]').click(); + await page.locator('[aria-label="More Info"]').click(); + const [page3] = await Promise.all([ + page.waitForEvent('popup'), + page.locator('button:has-text("Learn more")').click() + ]); + expect(page3.url().indexOf('https://learn.microsoft.com/')).toBeGreaterThan(-1); + }) + + test('should launch the share query dialog when share query button is clicked', async () => { + await page.locator('[aria-label="Share query"]').click(); + await page.evaluate(() => document.fonts.ready); + expect(page.locator('div[role="heading"]:has-text("Share Query")')).toBeDefined(); + // eslint-disable-next-line max-len + expect(page.locator('text=Share this link to let people try your current query in the Graph Explorer')).toBeDefined(); + // eslint-disable-next-line max-len + expect(page.locator('text=https://developer.microsoft.com/en-us/graph/graph-explorer?request=me&method=GET')).toBeDefined(); + await page.locator('button:has-text("Copy")').click(); + await page.evaluate(() => document.fonts.ready); + await page.waitForTimeout(200); + expect(await page.screenshot({ clip: { x: 300, y: 0, width: 1920, height: 400 } })).toMatchSnapshot(); + expect(page.locator('button:has-text("Copied")')).toBeDefined(); + await page.locator('button:has-text("Close")').click(); + await page.evaluate(() => document.fonts.ready); + await page.waitForTimeout(200); + expect(await page.screenshot({ clip: { x: 300, y: 0, width: 1920, height: 400 } })).toMatchSnapshot(); + }); + +}); + +test.describe.serial('Request section', () => { + test('should add request headers', async () => { + const queryInput = page.locator('[aria-label="Query sample input"]'); + await queryInput.click(); + queryInput.fill('https://graph.microsoft.com/v1.0/users?$count=true'); + await page.locator('[aria-label="Request headers"]').click(); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot({ clip: { x: 300, y: 0, width: 1920, height: 400 } })).toMatchSnapshot(); + await page.locator('[placeholder="Key"]').click(); + await page.locator('[placeholder="Key"]').fill('ConsistencyLevel'); + await page.locator('[placeholder="Key"]').press('Tab'); + await page.locator('[placeholder="Value"]').fill('eventual'); + await page.locator('button:has-text("Add")').click(); + await page.evaluate(() => document.fonts.ready); + await page.waitForTimeout(200); + expect(await page.screenshot({ clip: { x: 300, y: 0, width: 1920, height: 400 } })).toMatchSnapshot(); + await page.locator('button[role="button"]:has-text("Run query")').click(); + expect(page.locator('text=ConsistencyLevel')).toBeDefined(); + expect(page.locator('text=eventual')).toBeDefined(); + }); + + test('should edit request headers', async () => { + await page.locator('[aria-label="Edit request header"]').click(); + await page.locator('[placeholder="Key"]').fill('ConsistencyLev'); + await page.evaluate(() => document.fonts.ready); + await page.waitForTimeout(200); + expect(await page.screenshot({ clip: { x: 300, y: 0, width: 1920, height: 400 } })).toMatchSnapshot(); + await page.locator('button:has-text("Update")').click(); + await page.evaluate(() => document.fonts.ready); + await page.waitForTimeout(200); + expect(await page.screenshot({ clip: { x: 300, y: 0, width: 1920, height: 400 } })).toMatchSnapshot(); + const newHeaderKey = page.locator('text=ConsistencyLev'); + expect(newHeaderKey).toBeDefined(); + }); +}) + +test.describe('Permissions', () => { + test('should show permissions for /me endpoint', async () => { + await page.locator('button[role="tab"]:has-text(" Sample queries")').click(); + await page.locator('[aria-label="my profile"]').click(); + await page.locator('[aria-label="Modify permissions"]').click(); + await page.evaluate(() => document.fonts.ready); + await page.waitForTimeout(500); + const permissionsText = page.locator('text=One of the following permissions is required to run the query. Sign in with an a'); + expect(permissionsText).toBeDefined(); + expect(await page.screenshot({ clip: { x: 0, y: 0, width: 1920, height: 400 } })).toMatchSnapshot(); + const DirectoryPermission = page.locator('div[role="gridcell"]:has-text("Directory.Read.AllDirectory.Read.All")'); + expect(DirectoryPermission).toBeDefined(); + }) +}) + +test.describe('Access token tab', () => { + test('should show access token message when not authenticated ', async () => { + await page.locator('[aria-label="Access token"]').click(); + await page.evaluate(() => document.fonts.ready); + const tokenMessage = page.locator('text=To view your access token, sign in to Graph Explorer.'); + expect(tokenMessage).toBeDefined(); + expect(await page.screenshot({ clip: { x: 300, y: 0, width: 1920, height: 400 } })).toMatchSnapshot(); + }) +}) + + diff --git a/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Access-token-tab-should-show-access-token-message-when-not-authenticated-1-win32.png b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Access-token-tab-should-show-access-token-message-when-not-authenticated-1-win32.png new file mode 100644 index 0000000000..74e2baa15c Binary files /dev/null and b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Access-token-tab-should-show-access-token-message-when-not-authenticated-1-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Permissions-should-show-permissions-for-me-endpoint-1-win32.png b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Permissions-should-show-permissions-for-me-endpoint-1-win32.png new file mode 100644 index 0000000000..e1d47f3f29 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Permissions-should-show-permissions-for-me-endpoint-1-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Request-section-should-add-request-headers-1-win32.png b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Request-section-should-add-request-headers-1-win32.png new file mode 100644 index 0000000000..2835e7a579 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Request-section-should-add-request-headers-1-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Request-section-should-add-request-headers-2-win32.png b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Request-section-should-add-request-headers-2-win32.png new file mode 100644 index 0000000000..7e290b1ef0 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Request-section-should-add-request-headers-2-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Request-section-should-delete-request-headers-1-win32.png b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Request-section-should-delete-request-headers-1-win32.png new file mode 100644 index 0000000000..6f4f15fb22 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Request-section-should-delete-request-headers-1-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Request-section-should-edit-request-headers-1-win32.png b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Request-section-should-edit-request-headers-1-win32.png new file mode 100644 index 0000000000..74d6fafa6b Binary files /dev/null and b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Request-section-should-edit-request-headers-1-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Request-section-should-edit-request-headers-2-win32.png b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Request-section-should-edit-request-headers-2-win32.png new file mode 100644 index 0000000000..aeae362340 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Request-section-should-edit-request-headers-2-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Request-section-should-show-access-token-message-when-not-authenticated-1-win32.png b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Request-section-should-show-access-token-message-when-not-authenticated-1-win32.png new file mode 100644 index 0000000000..78087291f3 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Request-section-should-show-access-token-message-when-not-authenticated-1-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Request-section-should-show-permissions-for-me-endpoint-1-win32.png b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Request-section-should-show-permissions-for-me-endpoint-1-win32.png new file mode 100644 index 0000000000..f1d72325c5 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Request-section-should-show-permissions-for-me-endpoint-1-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-Adds-message-and-gets-autocomplete-options-1-win32.png b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-Adds-message-and-gets-autocomplete-options-1-win32.png new file mode 100644 index 0000000000..90e517d885 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-Adds-message-and-gets-autocomplete-options-1-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-Adds-message-and-gets-autocomplete-options-2-win32.png b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-Adds-message-and-gets-autocomplete-options-2-win32.png new file mode 100644 index 0000000000..612e4e9566 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-Adds-message-and-gets-autocomplete-options-2-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-Adds-message-and-gets-autocomplete-options-3-win32.png b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-Adds-message-and-gets-autocomplete-options-3-win32.png new file mode 100644 index 0000000000..56505077de Binary files /dev/null and b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-Adds-message-and-gets-autocomplete-options-3-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-Adds-message-and-gets-autocomplete-options-4-win32.png b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-Adds-message-and-gets-autocomplete-options-4-win32.png new file mode 100644 index 0000000000..2a8f68c812 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-Adds-message-and-gets-autocomplete-options-4-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-Changing-the-version-via-the-dropdown-menu-changes-the-version-in-the-request-URL-field-1-win32.png b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-Changing-the-version-via-the-dropdown-menu-changes-the-version-in-the-request-URL-field-1-win32.png new file mode 100644 index 0000000000..e93fe8565f Binary files /dev/null and b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-Changing-the-version-via-the-dropdown-menu-changes-the-version-in-the-request-URL-field-1-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-Changing-the-version-via-the-dropdown-menu-changes-the-version-in-the-request-URL-field-2-win32.png b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-Changing-the-version-via-the-dropdown-menu-changes-the-version-in-the-request-URL-field-2-win32.png new file mode 100644 index 0000000000..e360a2d187 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-Changing-the-version-via-the-dropdown-menu-changes-the-version-in-the-request-URL-field-2-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-Changing-the-version-via-the-dropdown-menu-changes-the-version-in-the-request-URL-field-3-win32.png b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-Changing-the-version-via-the-dropdown-menu-changes-the-version-in-the-request-URL-field-3-win32.png new file mode 100644 index 0000000000..c83619d028 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-Changing-the-version-via-the-dropdown-menu-changes-the-version-in-the-request-URL-field-3-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-Changing-the-version-via-the-dropdown-menu-changes-the-version-in-the-request-URL-field-4-win32.png b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-Changing-the-version-via-the-dropdown-menu-changes-the-version-in-the-request-URL-field-4-win32.png new file mode 100644 index 0000000000..54dd8c8120 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-Changing-the-version-via-the-dropdown-menu-changes-the-version-in-the-request-URL-field-4-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-Changing-the-version-via-the-request-URL-field-changes-the-version-in-the-dropdown-1-win32.png b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-Changing-the-version-via-the-request-URL-field-changes-the-version-in-the-dropdown-1-win32.png new file mode 100644 index 0000000000..29081b49b0 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-Changing-the-version-via-the-request-URL-field-changes-the-version-in-the-dropdown-1-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-Changing-the-version-via-the-request-URL-field-changes-the-version-in-the-dropdown-2-win32.png b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-Changing-the-version-via-the-request-URL-field-changes-the-version-in-the-dropdown-2-win32.png new file mode 100644 index 0000000000..90e517d885 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-Changing-the-version-via-the-request-URL-field-changes-the-version-in-the-dropdown-2-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-should-change-version-options-1-win32.png b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-should-change-version-options-1-win32.png new file mode 100644 index 0000000000..bf5daa4d97 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-should-change-version-options-1-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-should-change-version-options-2-win32.png b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-should-change-version-options-2-win32.png new file mode 100644 index 0000000000..e266da8504 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-should-change-version-options-2-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-should-change-version-options-3-win32.png b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-should-change-version-options-3-win32.png new file mode 100644 index 0000000000..31218ca645 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-should-change-version-options-3-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-should-change-version-options-4-win32.png b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-should-change-version-options-4-win32.png new file mode 100644 index 0000000000..923086401a Binary files /dev/null and b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-should-change-version-options-4-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-should-change-version-options-5-win32.png b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-should-change-version-options-5-win32.png new file mode 100644 index 0000000000..5fb1d1c8a2 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-should-change-version-options-5-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-should-launch-the-share-query-dialog-when-share-query-button-is-clicked-1-win32.png b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-should-launch-the-share-query-dialog-when-share-query-button-is-clicked-1-win32.png new file mode 100644 index 0000000000..f105e5bd0d Binary files /dev/null and b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-should-launch-the-share-query-dialog-when-share-query-button-is-clicked-1-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-should-launch-the-share-query-dialog-when-share-query-button-is-clicked-2-win32.png b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-should-launch-the-share-query-dialog-when-share-query-button-is-clicked-2-win32.png new file mode 100644 index 0000000000..80c58cc759 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-should-launch-the-share-query-dialog-when-share-query-button-is-clicked-2-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-user-can-run-query-1-win32.png b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-user-can-run-query-1-win32.png new file mode 100644 index 0000000000..56554c4632 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-user-can-run-query-1-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-user-can-run-query-2-win32.png b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-user-can-run-query-2-win32.png new file mode 100644 index 0000000000..75f61b431c Binary files /dev/null and b/src/tests/ui/anonymous-experiences/request.spec.ts-snapshots/Run-query-user-can-run-query-2-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/response.spec.ts b/src/tests/ui/anonymous-experiences/response.spec.ts new file mode 100644 index 0000000000..70c3331be8 --- /dev/null +++ b/src/tests/ui/anonymous-experiences/response.spec.ts @@ -0,0 +1,91 @@ +/* eslint-disable max-len */ +import { test, expect, Page } from '@playwright/test'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); + await page.goto('/'); +}); + +test.describe('Response section', () => { + test('should show a response for a successful request', async () => { + await page.locator('button[role="button"]:has-text("Run query")').click(); + const response = page.locator('text=/.*"displayName".*/'); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot({ clip: { x: 300, y: -200, width: 1920, height: 1080 } })).toMatchSnapshot(); + expect(response).toBeDefined(); + }) + + test('should show snippets for the selected language', async () => { + const queryInput = page.locator('[aria-label="Query sample input"]'); + await queryInput.click(); + queryInput.fill('https://graph.microsoft.com/v1.0/me/messages'); + await queryInput.press('Tab'); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot({ clip: { x: 300, y: -200, width: 1920, height: 1080 } })).toMatchSnapshot(); + const snippetTab = page.locator('[aria-label="Code snippets"]'); + await snippetTab.click(); + await page.waitForTimeout(200); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot({ clip: { x: 300, y: -200, width: 1920, height: 1080 } })).toMatchSnapshot(); + const cSharpTab = page.locator('button[role="tab"]:has-text("CSharp")'); + await cSharpTab.click(); + await page.waitForTimeout(200); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot({ clip: { x: 300, y: -200, width: 1920, height: 1080 } })).toMatchSnapshot(); + await page.locator('button[role="tab"]:has-text("JavaScript")').click(); + await page.locator('button[name="Java"]').click(); + await page.waitForTimeout(200); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot({ clip: { x: 300, y: -200, width: 1920, height: 1080 } })).toMatchSnapshot(); + await page.locator('button[role="tab"]:has-text("Go")').click(); + await page.locator('button[role="tab"]:has-text("PowerShell")').click(); + await page.waitForTimeout(200); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot({ clip: { x: 300, y: -200, width: 1920, height: 1080 } })).toMatchSnapshot(); + }); + + test('should show toolkit component for a valid url', async () => { + const queryInput = page.locator('[aria-label="Query sample input"]'); + await queryInput.click(); + await queryInput.fill('https://graph.microsoft.com/me'); + await page.waitForTimeout(200); + expect(await page.screenshot({ clip: { x: 300, y: -200, width: 1920, height: 1080 } })).toMatchSnapshot(); + const toolkitTab = page.locator('[aria-label="Toolkit component"]'); + await toolkitTab.click(); + await page.waitForTimeout(200); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot({ clip: { x: 300, y: -200, width: 1920, height: 1080 } })).toMatchSnapshot(); + expect(page.locator('text=Open this example in')).toBeDefined(); + }); + + test('should show an error message for an invalid url', async () => { + const queryInput = page.locator('[aria-label="Query sample input"]'); + await queryInput.click(); + await queryInput.fill('https://graph.microsoft.com/me/messages'); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot({ clip: { x: 300, y: -200, width: 1920, height: 1080 } })).toMatchSnapshot(); + const toolkitTab = page.locator('[aria-label="Toolkit component"]'); + await toolkitTab.click(); + await page.waitForTimeout(200); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot({ clip: { x: 300, y: -200, width: 1920, height: 1080 } })).toMatchSnapshot(); + expect(page.locator('text=No toolkit component is available')).toBeDefined(); + }) + + test('should open an expanded modal with response tabs when Expand is clicked', async () => { + await page.locator('[aria-label="Expand response"]').click(); + await page.waitForTimeout(200); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot()).toMatchSnapshot(); + await page.locator('text= Response preview Response headers Code snippets Toolkit component Adaptiv >> [aria-label="Response headers"]').click(); + await page.locator('text= Response preview Response headers Code snippets Toolkit component Adaptiv >> [aria-label="Code snippets"]').click(); + await page.locator('text= Response preview Response headers Code snippets Toolkit component Adaptiv >> [aria-label="Toolkit component"]').click(); + await page.locator('text= Response preview Response headers Code snippets Toolkit component Adaptiv >> [aria-label="Adaptive cards"]').click(); + await page.locator('[aria-label="Close expanded response area"]').click(); + await page.waitForTimeout(200); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot()).toMatchSnapshot(); + }) +}) \ No newline at end of file diff --git a/src/tests/ui/anonymous-experiences/response.spec.ts-snapshots/Response-section-should-open-an-expanded-modal-with-response-tabs-when-Expand-is-clicked-1-win32.png b/src/tests/ui/anonymous-experiences/response.spec.ts-snapshots/Response-section-should-open-an-expanded-modal-with-response-tabs-when-Expand-is-clicked-1-win32.png new file mode 100644 index 0000000000..4d1483a57a Binary files /dev/null and b/src/tests/ui/anonymous-experiences/response.spec.ts-snapshots/Response-section-should-open-an-expanded-modal-with-response-tabs-when-Expand-is-clicked-1-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/response.spec.ts-snapshots/Response-section-should-open-an-expanded-modal-with-response-tabs-when-Expand-is-clicked-2-win32.png b/src/tests/ui/anonymous-experiences/response.spec.ts-snapshots/Response-section-should-open-an-expanded-modal-with-response-tabs-when-Expand-is-clicked-2-win32.png new file mode 100644 index 0000000000..61d8e1dea1 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/response.spec.ts-snapshots/Response-section-should-open-an-expanded-modal-with-response-tabs-when-Expand-is-clicked-2-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/response.spec.ts-snapshots/Response-section-should-show-a-response-for-a-successful-request-1-win32.png b/src/tests/ui/anonymous-experiences/response.spec.ts-snapshots/Response-section-should-show-a-response-for-a-successful-request-1-win32.png new file mode 100644 index 0000000000..f7f083a817 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/response.spec.ts-snapshots/Response-section-should-show-a-response-for-a-successful-request-1-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/response.spec.ts-snapshots/Response-section-should-show-an-error-message-for-an-invalid-url-1-win32.png b/src/tests/ui/anonymous-experiences/response.spec.ts-snapshots/Response-section-should-show-an-error-message-for-an-invalid-url-1-win32.png new file mode 100644 index 0000000000..410e23a18d Binary files /dev/null and b/src/tests/ui/anonymous-experiences/response.spec.ts-snapshots/Response-section-should-show-an-error-message-for-an-invalid-url-1-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/response.spec.ts-snapshots/Response-section-should-show-an-error-message-for-an-invalid-url-2-win32.png b/src/tests/ui/anonymous-experiences/response.spec.ts-snapshots/Response-section-should-show-an-error-message-for-an-invalid-url-2-win32.png new file mode 100644 index 0000000000..37d20539a2 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/response.spec.ts-snapshots/Response-section-should-show-an-error-message-for-an-invalid-url-2-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/response.spec.ts-snapshots/Response-section-should-show-snippets-for-the-selected-language-1-win32.png b/src/tests/ui/anonymous-experiences/response.spec.ts-snapshots/Response-section-should-show-snippets-for-the-selected-language-1-win32.png new file mode 100644 index 0000000000..957c63f4e8 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/response.spec.ts-snapshots/Response-section-should-show-snippets-for-the-selected-language-1-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/response.spec.ts-snapshots/Response-section-should-show-snippets-for-the-selected-language-2-win32.png b/src/tests/ui/anonymous-experiences/response.spec.ts-snapshots/Response-section-should-show-snippets-for-the-selected-language-2-win32.png new file mode 100644 index 0000000000..8bad12bccd Binary files /dev/null and b/src/tests/ui/anonymous-experiences/response.spec.ts-snapshots/Response-section-should-show-snippets-for-the-selected-language-2-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/response.spec.ts-snapshots/Response-section-should-show-snippets-for-the-selected-language-3-win32.png b/src/tests/ui/anonymous-experiences/response.spec.ts-snapshots/Response-section-should-show-snippets-for-the-selected-language-3-win32.png new file mode 100644 index 0000000000..6a0ae22abb Binary files /dev/null and b/src/tests/ui/anonymous-experiences/response.spec.ts-snapshots/Response-section-should-show-snippets-for-the-selected-language-3-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/response.spec.ts-snapshots/Response-section-should-show-snippets-for-the-selected-language-4-win32.png b/src/tests/ui/anonymous-experiences/response.spec.ts-snapshots/Response-section-should-show-snippets-for-the-selected-language-4-win32.png new file mode 100644 index 0000000000..c9d8d2bc71 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/response.spec.ts-snapshots/Response-section-should-show-snippets-for-the-selected-language-4-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/response.spec.ts-snapshots/Response-section-should-show-snippets-for-the-selected-language-5-win32.png b/src/tests/ui/anonymous-experiences/response.spec.ts-snapshots/Response-section-should-show-snippets-for-the-selected-language-5-win32.png new file mode 100644 index 0000000000..7172e10da1 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/response.spec.ts-snapshots/Response-section-should-show-snippets-for-the-selected-language-5-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/response.spec.ts-snapshots/Response-section-should-show-toolkit-component-for-a-valid-url-1-win32.png b/src/tests/ui/anonymous-experiences/response.spec.ts-snapshots/Response-section-should-show-toolkit-component-for-a-valid-url-1-win32.png new file mode 100644 index 0000000000..ba4896e280 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/response.spec.ts-snapshots/Response-section-should-show-toolkit-component-for-a-valid-url-1-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/response.spec.ts-snapshots/Response-section-should-show-toolkit-component-for-a-valid-url-2-win32.png b/src/tests/ui/anonymous-experiences/response.spec.ts-snapshots/Response-section-should-show-toolkit-component-for-a-valid-url-2-win32.png new file mode 100644 index 0000000000..d13cb7b409 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/response.spec.ts-snapshots/Response-section-should-show-toolkit-component-for-a-valid-url-2-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/sidebar.spec.ts b/src/tests/ui/anonymous-experiences/sidebar.spec.ts new file mode 100644 index 0000000000..b6a34f87a2 --- /dev/null +++ b/src/tests/ui/anonymous-experiences/sidebar.spec.ts @@ -0,0 +1,143 @@ +/* eslint-disable max-len */ +import { test, expect, Page } from '@playwright/test'; + +let page: Page; + +test.beforeAll(async ({ browser }) => { + page = await browser.newPage(); + await page.goto('/'); +}); + +test.describe('Resources Explorer', () => { + test('should open the resources explorer when the resources explorer button is clicked', async () => { + await page.locator('button[role="tab"]:has-text("Resources")').click(); + await page.evaluate(() => document.fonts.ready); + await page.waitForTimeout(200); + expect(await page.screenshot()).toMatchSnapshot(); + await page.locator('text=admin (3)').click(); + await page.locator('text=admin').nth(1).click(); + await page.waitForTimeout(200); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot()).toMatchSnapshot(); + const queryInputField = page.locator('[aria-label="Query sample input"]'); + await queryInputField.click(); + await page.evaluate(() => document.fonts.ready); + await page.waitForTimeout(200); + expect(await page.screenshot()).toMatchSnapshot(); + const queryInputValue = await queryInputField.inputValue(); + expect(queryInputValue).toBe('https://graph.microsoft.com/v1.0/admin'); + }); + + test('should isolate a resource when the isolate button is clicked', async () => { + await page.locator('button[role="tab"]:has-text("Resources")').click(); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot()).toMatchSnapshot(); + await page.locator('text=admin (3)More actions >> [aria-label="More actions"]').click(); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot()).toMatchSnapshot(); + await page.locator('button[role="menuitem"]:has-text("Isolate")').click(); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot()).toMatchSnapshot(); + await page.locator('button:has-text("Close isolation")').click(); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot()).toMatchSnapshot(); + }); + + test('should add a resource to collection', async () => { + await page.locator('button[role="tab"]:has-text("Resources")').click(); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot()).toMatchSnapshot(); + await page.locator('text=admin (3)').click(); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot()).toMatchSnapshot(); + await page.locator('text=GETadminMore actions >> [aria-label="More actions"]').click(); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot()).toMatchSnapshot(); + await page.locator('button[role="menuitem"]:has-text("Add to collection")').click(); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot()).toMatchSnapshot(); + await page.locator('[aria-label="Preview collection"]').click(); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot()).toMatchSnapshot(); + const [download] = await Promise.all([ + page.waitForEvent('download'), + page.locator('button:has-text("Download Postman collection")').click() + ]); + expect(download.suggestedFilename().indexOf('postman_collection.json')).toBeGreaterThan(-1); + await page.locator('[aria-label="select row"]').click(); + await page.locator('button[role="menuitem"]:has-text("Remove")').click(); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot()).toMatchSnapshot(); + }); + + test('should switch between v1 and beta versions of resources', async () => { + await page.locator('button[role="tab"]:has-text("Resources")').click(); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot()).toMatchSnapshot(); + await page.locator('button[role="switch"]').click(); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot()).toMatchSnapshot(); + expect(page.locator('label:has-text("On")')).toBeDefined(); + }) +}) + +test.describe('History tab', () => { + test('should show added history items to Today\'s collection ', async () => { + await page.locator('button[role="button"]:has-text("Run query")').click(); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot()).toMatchSnapshot(); + await page.locator('text= Sample queries Resources History >> [aria-label="More items"]').click(); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot()).toMatchSnapshot(); + await page.locator('button[role="menuitem"]:has-text("History")').click(); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot()).toMatchSnapshot(); + expect(page.locator('span:has-text("Today")')).toBeDefined(); + }); +}); + +test.describe.serial('Sample Query tab', () => { + + test('should select a sample query when clicked', async () => { + await page.locator('button[role="tab"]:has-text(" Sample queries")').click(); + await page.evaluate(() => document.fonts.ready); + await page.waitForTimeout(200); + expect(await page.screenshot()).toMatchSnapshot(); + expect(page.locator('text=Getting Started')).toBeDefined(); + await page.locator('[aria-label="getmy profile"] span:has-text("GET")').click(); + await page.evaluate(() => document.fonts.ready); + await page.waitForTimeout(200); + expect(await page.screenshot()).toMatchSnapshot(); + await page.locator('button[role="button"]:has-text("Run query")').click(); + await page.evaluate(() => document.fonts.ready); + await page.waitForTimeout(200); + expect(await page.screenshot()).toMatchSnapshot(); + const [page4] = await Promise.all([ + page.waitForEvent('popup'), + page.locator('div[role="gridcell"]:has-text("https://docs.microsoft.com/en-us/graph/api/user-get")').click() + ]); + expect(page4).toBeDefined(); + }) + + test('should search for a sample query', async () => { + await page.locator('button[role="tab"]:has-text(" Sample queries")').click(); + await page.evaluate(() => document.fonts.ready); + await page.waitForTimeout(200); + expect(await page.screenshot()).toMatchSnapshot(); + await page.locator('[placeholder="Search sample queries"]').click(); + await page.locator('[placeholder="Search sample queries"]').fill('drive'); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot()).toMatchSnapshot(); + await page.locator('[aria-label="all the items in my drive"]').click(); + await page.evaluate(() => document.fonts.ready); + await page.waitForTimeout(200); + expect(await page.screenshot()).toMatchSnapshot(); + await page.locator('[aria-label="OneDrive has 5 results 4 of 5"] [aria-label="expand collapse group"]').click(); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot()).toMatchSnapshot(); + await page.locator('[aria-label="my recent files"]').click(); + await page.waitForTimeout(200); + await page.evaluate(() => document.fonts.ready); + expect(await page.screenshot()).toMatchSnapshot(); + }) +}) \ No newline at end of file diff --git a/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/History-tab-should-show-added-history-items-to-Today-s-collection-1-win32.png b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/History-tab-should-show-added-history-items-to-Today-s-collection-1-win32.png new file mode 100644 index 0000000000..438efaed54 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/History-tab-should-show-added-history-items-to-Today-s-collection-1-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/History-tab-should-show-added-history-items-to-Today-s-collection-2-win32.png b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/History-tab-should-show-added-history-items-to-Today-s-collection-2-win32.png new file mode 100644 index 0000000000..fa017b27f6 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/History-tab-should-show-added-history-items-to-Today-s-collection-2-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/History-tab-should-show-added-history-items-to-Today-s-collection-3-win32.png b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/History-tab-should-show-added-history-items-to-Today-s-collection-3-win32.png new file mode 100644 index 0000000000..759f62536f Binary files /dev/null and b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/History-tab-should-show-added-history-items-to-Today-s-collection-3-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-add-a-resource-to-collection-1-win32.png b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-add-a-resource-to-collection-1-win32.png new file mode 100644 index 0000000000..32b74c8f40 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-add-a-resource-to-collection-1-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-add-a-resource-to-collection-2-win32.png b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-add-a-resource-to-collection-2-win32.png new file mode 100644 index 0000000000..08ad047a81 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-add-a-resource-to-collection-2-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-add-a-resource-to-collection-3-win32.png b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-add-a-resource-to-collection-3-win32.png new file mode 100644 index 0000000000..a60e9d4b32 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-add-a-resource-to-collection-3-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-add-a-resource-to-collection-4-win32.png b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-add-a-resource-to-collection-4-win32.png new file mode 100644 index 0000000000..8cc365d616 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-add-a-resource-to-collection-4-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-add-a-resource-to-collection-5-win32.png b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-add-a-resource-to-collection-5-win32.png new file mode 100644 index 0000000000..d536614954 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-add-a-resource-to-collection-5-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-add-a-resource-to-collection-6-win32.png b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-add-a-resource-to-collection-6-win32.png new file mode 100644 index 0000000000..3b18dfda12 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-add-a-resource-to-collection-6-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-isolate-a-resource-when-the-isolate-button-is-clicked-1-win32.png b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-isolate-a-resource-when-the-isolate-button-is-clicked-1-win32.png new file mode 100644 index 0000000000..557b6318dd Binary files /dev/null and b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-isolate-a-resource-when-the-isolate-button-is-clicked-1-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-isolate-a-resource-when-the-isolate-button-is-clicked-2-win32.png b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-isolate-a-resource-when-the-isolate-button-is-clicked-2-win32.png new file mode 100644 index 0000000000..d3744af91f Binary files /dev/null and b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-isolate-a-resource-when-the-isolate-button-is-clicked-2-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-isolate-a-resource-when-the-isolate-button-is-clicked-3-win32.png b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-isolate-a-resource-when-the-isolate-button-is-clicked-3-win32.png new file mode 100644 index 0000000000..8c80aa617e Binary files /dev/null and b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-isolate-a-resource-when-the-isolate-button-is-clicked-3-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-isolate-a-resource-when-the-isolate-button-is-clicked-4-win32.png b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-isolate-a-resource-when-the-isolate-button-is-clicked-4-win32.png new file mode 100644 index 0000000000..faaada3a54 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-isolate-a-resource-when-the-isolate-button-is-clicked-4-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-open-the-resources-e-32f57-when-the-resources-explorer-button-is-clicked-1-win32.png b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-open-the-resources-e-32f57-when-the-resources-explorer-button-is-clicked-1-win32.png new file mode 100644 index 0000000000..557b6318dd Binary files /dev/null and b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-open-the-resources-e-32f57-when-the-resources-explorer-button-is-clicked-1-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-open-the-resources-e-a7aea-when-the-resources-explorer-button-is-clicked-2-win32.png b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-open-the-resources-e-a7aea-when-the-resources-explorer-button-is-clicked-2-win32.png new file mode 100644 index 0000000000..6f098db32f Binary files /dev/null and b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-open-the-resources-e-a7aea-when-the-resources-explorer-button-is-clicked-2-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-open-the-resources-e-a813e-when-the-resources-explorer-button-is-clicked-3-win32.png b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-open-the-resources-e-a813e-when-the-resources-explorer-button-is-clicked-3-win32.png new file mode 100644 index 0000000000..ab5484efe2 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-open-the-resources-e-a813e-when-the-resources-explorer-button-is-clicked-3-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-switch-between-v1-and-beta-versions-of-resources-1-win32.png b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-switch-between-v1-and-beta-versions-of-resources-1-win32.png new file mode 100644 index 0000000000..68990f9628 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-switch-between-v1-and-beta-versions-of-resources-1-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-switch-between-v1-and-beta-versions-of-resources-2-win32.png b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-switch-between-v1-and-beta-versions-of-resources-2-win32.png new file mode 100644 index 0000000000..ca59b71db1 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Resources-Explorer-should-switch-between-v1-and-beta-versions-of-resources-2-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Sample-Query-tab-should-search-for-a-sample-query-1-win32.png b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Sample-Query-tab-should-search-for-a-sample-query-1-win32.png new file mode 100644 index 0000000000..2aebfcbc90 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Sample-Query-tab-should-search-for-a-sample-query-1-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Sample-Query-tab-should-search-for-a-sample-query-2-win32.png b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Sample-Query-tab-should-search-for-a-sample-query-2-win32.png new file mode 100644 index 0000000000..8cf15579cb Binary files /dev/null and b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Sample-Query-tab-should-search-for-a-sample-query-2-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Sample-Query-tab-should-search-for-a-sample-query-3-win32.png b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Sample-Query-tab-should-search-for-a-sample-query-3-win32.png new file mode 100644 index 0000000000..2bbf5cccbf Binary files /dev/null and b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Sample-Query-tab-should-search-for-a-sample-query-3-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Sample-Query-tab-should-search-for-a-sample-query-4-win32.png b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Sample-Query-tab-should-search-for-a-sample-query-4-win32.png new file mode 100644 index 0000000000..e843c045b7 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Sample-Query-tab-should-search-for-a-sample-query-4-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Sample-Query-tab-should-search-for-a-sample-query-5-win32.png b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Sample-Query-tab-should-search-for-a-sample-query-5-win32.png new file mode 100644 index 0000000000..d43d547ebc Binary files /dev/null and b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Sample-Query-tab-should-search-for-a-sample-query-5-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Sample-Query-tab-should-select-a-sample-query-when-clicked-1-win32.png b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Sample-Query-tab-should-select-a-sample-query-when-clicked-1-win32.png new file mode 100644 index 0000000000..f00d12f68a Binary files /dev/null and b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Sample-Query-tab-should-select-a-sample-query-when-clicked-1-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Sample-Query-tab-should-select-a-sample-query-when-clicked-2-win32.png b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Sample-Query-tab-should-select-a-sample-query-when-clicked-2-win32.png new file mode 100644 index 0000000000..1207cd3212 Binary files /dev/null and b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Sample-Query-tab-should-select-a-sample-query-when-clicked-2-win32.png differ diff --git a/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Sample-Query-tab-should-select-a-sample-query-when-clicked-3-win32.png b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Sample-Query-tab-should-select-a-sample-query-when-clicked-3-win32.png new file mode 100644 index 0000000000..75f61b431c Binary files /dev/null and b/src/tests/ui/anonymous-experiences/sidebar.spec.ts-snapshots/Sample-Query-tab-should-select-a-sample-query-when-clicked-3-win32.png differ diff --git a/src/tests/ui/authenticated-experiences/authenticated-experiences.spec.ts b/src/tests/ui/authenticated-experiences/authenticated-experiences.spec.ts new file mode 100644 index 0000000000..d5cdfa4e4f --- /dev/null +++ b/src/tests/ui/authenticated-experiences/authenticated-experiences.spec.ts @@ -0,0 +1,61 @@ +/* eslint-disable max-len */ +import { test, expect, Page } from '@playwright/test'; +import { logIn } from '../login'; +require('dotenv').config(); + +let authenticatedPage: Page; + +test.beforeAll(async ({ browser }) => { + authenticatedPage = await browser.newPage(); + await logIn(authenticatedPage); +}); + +test.describe('Run query', () => { + + test('user can run query', async () => { + const runQueryButton = authenticatedPage.locator('.run-query-button button'); + await runQueryButton.click(); + await authenticatedPage.waitForTimeout(100); + await authenticatedPage.evaluate(() => document.fonts.ready); + expect(await authenticatedPage.screenshot()).toMatchSnapshot(); + const messageBar = authenticatedPage.locator('.ms-MessageBar-content'); + expect(messageBar).toBeDefined(); + await expect(authenticatedPage.locator('text=/.*"displayName": "Megan Bowen".*/')).not.toBeVisible(); + }); + +}); + +test.describe('Request', () => { + test('Access token is available and is decodeable', async () => { + await authenticatedPage.locator('[aria-label="Access token"]').click(); + await authenticatedPage.locator('[aria-label="Copy"]').click(); + await authenticatedPage.waitForTimeout(100); + await authenticatedPage.evaluate(() => document.fonts.ready); + expect(await authenticatedPage.screenshot({ clip: { x: 300, y: 0, width: 1920, height: 200 } })).toMatchSnapshot(); + const [page5] = await Promise.all([ + authenticatedPage.waitForEvent('popup'), + authenticatedPage.locator('[aria-label="Get token details \\(Powered by jwt\\.ms\\)"]').click() + ]); + expect(page5.url().indexOf('https://jwt.ms/')).toBeGreaterThan(-1); + }) +}) + +test.describe.serial('Profile', () => { + test('should show profile', async () => { + await authenticatedPage.locator('[aria-label="profile"]').click(); + await authenticatedPage.waitForTimeout(100); + await authenticatedPage.evaluate(() => document.fonts.ready); + expect(await authenticatedPage.screenshot()).toMatchSnapshot(); + await expect(authenticatedPage.locator('button:has-text("Consent to permissions")')).toBeVisible(); + }); + + test('should open the permissions panel', async () => { + await authenticatedPage.locator('button:has-text("Consent to permissions")').click(); + await authenticatedPage.waitForTimeout(500); + await authenticatedPage.evaluate(() => document.fonts.ready); + expect(await authenticatedPage.screenshot()).toMatchSnapshot(); + await authenticatedPage.waitForTimeout(500); + expect(authenticatedPage.locator('div[role="heading"]:has-text("Permissions")')).toBeDefined(); + }) +}) + diff --git a/src/tests/ui/authenticated-experiences/authenticated-experiences.spec.ts-snapshots/Profile-should-open-the-permissions-panel-1-win32.png b/src/tests/ui/authenticated-experiences/authenticated-experiences.spec.ts-snapshots/Profile-should-open-the-permissions-panel-1-win32.png new file mode 100644 index 0000000000..9b417ab413 Binary files /dev/null and b/src/tests/ui/authenticated-experiences/authenticated-experiences.spec.ts-snapshots/Profile-should-open-the-permissions-panel-1-win32.png differ diff --git a/src/tests/ui/authenticated-experiences/authenticated-experiences.spec.ts-snapshots/Profile-should-show-profile-1-win32.png b/src/tests/ui/authenticated-experiences/authenticated-experiences.spec.ts-snapshots/Profile-should-show-profile-1-win32.png new file mode 100644 index 0000000000..9b55dc7c8e Binary files /dev/null and b/src/tests/ui/authenticated-experiences/authenticated-experiences.spec.ts-snapshots/Profile-should-show-profile-1-win32.png differ diff --git a/src/tests/ui/authenticated-experiences/authenticated-experiences.spec.ts-snapshots/Request-Access-token-is-available-and-is-decodeable-1-win32.png b/src/tests/ui/authenticated-experiences/authenticated-experiences.spec.ts-snapshots/Request-Access-token-is-available-and-is-decodeable-1-win32.png new file mode 100644 index 0000000000..82aa5a081e Binary files /dev/null and b/src/tests/ui/authenticated-experiences/authenticated-experiences.spec.ts-snapshots/Request-Access-token-is-available-and-is-decodeable-1-win32.png differ diff --git a/src/tests/ui/authenticated-experiences/authenticated-experiences.spec.ts-snapshots/Request-Access-token-is-available-and-is-decodeable-2-win32.png b/src/tests/ui/authenticated-experiences/authenticated-experiences.spec.ts-snapshots/Request-Access-token-is-available-and-is-decodeable-2-win32.png new file mode 100644 index 0000000000..bdf5d6c2ab Binary files /dev/null and b/src/tests/ui/authenticated-experiences/authenticated-experiences.spec.ts-snapshots/Request-Access-token-is-available-and-is-decodeable-2-win32.png differ diff --git a/src/tests/ui/authenticated-experiences/authenticated-experiences.spec.ts-snapshots/Run-query-user-can-run-query-1-win32.png b/src/tests/ui/authenticated-experiences/authenticated-experiences.spec.ts-snapshots/Run-query-user-can-run-query-1-win32.png new file mode 100644 index 0000000000..2ecdc6c076 Binary files /dev/null and b/src/tests/ui/authenticated-experiences/authenticated-experiences.spec.ts-snapshots/Run-query-user-can-run-query-1-win32.png differ diff --git a/src/tests/ui/global-setup.ts b/src/tests/ui/global-setup.ts new file mode 100644 index 0000000000..9a6a34074b --- /dev/null +++ b/src/tests/ui/global-setup.ts @@ -0,0 +1,10 @@ +import { chromium, FullConfig } from '@playwright/test'; + +async function globalSetup(config: FullConfig) { + const baseURL = config.projects[0].use.baseURL as string; + const browser = await chromium.launch(); + const page = await browser.newPage(); + await page.goto(baseURL); +} + +export default globalSetup; \ No newline at end of file diff --git a/src/tests/ui/login.ts b/src/tests/ui/login.ts new file mode 100644 index 0000000000..d2e8200dcf --- /dev/null +++ b/src/tests/ui/login.ts @@ -0,0 +1,27 @@ +import { expect } from '@playwright/test'; +require('dotenv').config(); + +const PLAYWRIGHT_TESTS_USERNAME = process.env.PLAYWRIGHT_TESTS_USERNAME || ''; +const PLAYWRIGHT_TESTS_PASSWORD = process.env.PLAYWRIGHT_TESTS_PASSWORD || ''; + +export const logIn = async (page: any) => { + + await page.goto('/'); + + const [popup] = await Promise.all([ + page.waitForEvent('popup'), + page.locator('[aria-label="Sign in"]').click() + ]); + + await popup.locator('input[name="loginfmt"]').fill(PLAYWRIGHT_TESTS_USERNAME); + await popup.locator('text=Next').click(); + + await popup.locator('[placeholder="Password"]').fill(PLAYWRIGHT_TESTS_PASSWORD); + await popup.locator('text=Sign in').click(); + + await expect(popup).toHaveURL('https://login.microsoftonline.com/common/login'); + const finalStep = popup.locator('text=Yes'); + if(finalStep.isVisible()) { + await finalStep.click(); + } +}; \ No newline at end of file