Skip to content

Commit

Permalink
E2E test improvements (#1106)
Browse files Browse the repository at this point in the history
* Build & lint `test-viewer`. Bump `tsc`. Add `dist` script.

* Supply enabled widgets through `widgets` query param

* Move e2e tests user authentication from test viewer to e2e tests, simplify test viewer startup

* Use production build of test-viewer for e2e tests

* Rewrite e2e tests pipeline as gh action

* Remove paths filter, or else the workflow can't be made required

* syntax

* link workspace deps before build

* don't require auth env variables when building test-viewer for e2e

* attempt to fix test-viewer-dist path

* print build args, correctly specify secrets

* put test-viewer dist to a subdir

* use the latest `mcr.microsoft.com/playwright:v1.49.0-noble` as e2e base image

* stop requesting deprecated scopes

* update `CONTRIBUTING.md`

* put back ability to enable widgets using `IMJS_ENABLED_WIDGETS` env var

* `auth` scripts should use `itwin-platform` scope

* change

* add missing eslint deps and fix warnings

* Mention the need to build test viewer before running e2e tests
  • Loading branch information
grigasp authored Dec 5, 2024
1 parent ebea235 commit afbd086
Show file tree
Hide file tree
Showing 39 changed files with 4,953 additions and 1,821 deletions.
159 changes: 159 additions & 0 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
name: E2E Tests

on:
workflow_dispatch:
pull_request:
branches: [master]
types: [opened, synchronize, reopened, ready_for_review]

jobs:
files-changed:
runs-on: ubuntu-latest
name: Detect what files changed
outputs:
test-viewer: ${{ steps.changes.outputs.test_viewer }}
tree-widget: ${{ steps.changes.outputs.tree_widget }}
property-grid: ${{ steps.changes.outputs.property_grid }}
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Check for file changes
uses: dorny/paths-filter@v3
id: changes
with:
filters: |
test_viewer:
- 'apps/test-viewer/**'
tree_widget:
- 'packages/itwin/tree-widget/**'
property_grid:
- 'packages/itwin/property-grid/**'
build-test-viewer:
name: Build test-viewer
needs: [files-changed]
if: ${{ needs.files-changed.outputs.test-viewer == 'true' || needs.files-changed.outputs.tree-widget == 'true' || needs.files-changed.outputs.property-grid == 'true' }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Install pnpm
uses: pnpm/action-setup@v3
with:
version: 9

- name: Use Node.js 20
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'

- name: Install dependencies
run: pnpm install

- name: Build dependencies
run: pnpm lage build --to test-viewer

- name: Build test-viewer
env:
IMJS_URL_PREFIX: "qa-"
IMJS_BUILD_MODE: "e2e"
run: pnpm run --dir apps/test-viewer dist

- name: Create test-viewer artifact
uses: actions/upload-artifact@v4
with:
name: test-viewer-dist
path: apps/test-viewer/dist

run-tests-tree-widget:
name: Run tree-widget tests
needs: [build-test-viewer, files-changed]
if: ${{ needs.files-changed.outputs.test-viewer == 'true' || needs.files-changed.outputs.tree-widget == 'true' }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Install pnpm
uses: pnpm/action-setup@v3
with:
version: 9

- name: Use Node.js 20
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'

- name: Install dependencies
run: pnpm install -D --filter ./packages/itwin/tree-widget

- name: Download test-viewer artifact
id: test-viewer-artifact
uses: actions/download-artifact@v4
with:
name: test-viewer-dist
path: test-viewer-dist

- name: Run tests in Docker
env:
CI: true
TEST_VIEWER_DIST: ${{ steps.test-viewer-artifact.outputs.download-path }}
IMJS_AUTH_CLIENT_CLIENT_ID: ${{ secrets.IMJS_AUTH_CLIENT_CLIENT_ID }}
IMJS_USER_EMAIL: ${{ secrets.IMJS_USER_EMAIL }}
IMJS_USER_PASSWORD: ${{ secrets.IMJS_USER_PASSWORD }}
run: pnpm run --dir packages/itwin/tree-widget test:e2e

- name: Publish test results artifact
uses: actions/upload-artifact@v4
with:
name: tree-widget-e2e-test-results
path: packages/itwin/tree-widget/e2e-out

run-tests-property-grid:
name: Run property-grid tests
needs: [build-test-viewer, files-changed]
if: ${{ needs.files-changed.outputs.test-viewer == 'true' || needs.files-changed.outputs.property-grid == 'true' }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Install pnpm
uses: pnpm/action-setup@v3
with:
version: 9

- name: Use Node.js 20
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'

- name: Install dependencies
run: pnpm install -D --filter ./packages/itwin/property-grid

- name: Download test-viewer artifact
id: test-viewer-artifact
uses: actions/download-artifact@v4
with:
name: test-viewer-dist
path: test-viewer-dist

- name: Run tests in Docker
env:
CI: true
TEST_VIEWER_DIST: ${{ steps.test-viewer-artifact.outputs.download-path }}
IMJS_AUTH_CLIENT_CLIENT_ID: ${{ secrets.IMJS_AUTH_CLIENT_CLIENT_ID }}
IMJS_USER_EMAIL: ${{ secrets.IMJS_USER_EMAIL }}
IMJS_USER_PASSWORD: ${{ secrets.IMJS_USER_PASSWORD }}
run: pnpm run --dir packages/itwin/property-grid test:e2e

- name: Publish test results artifact
uses: actions/upload-artifact@v4
with:
name: property-grid-e2e-test-results
path: packages/itwin/property-grid/e2e-out
4 changes: 1 addition & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,7 @@ package-lock.json
.node-xmlhttprequest-sync*

# e2e tests output
/**/test-results
/**/playwright-report
/**/playwright/.cache
/**/e2e-out

# api extractor temp files
/packages/**/api/temp
Expand Down
16 changes: 0 additions & 16 deletions .pipelines/pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,6 @@ jobs:
steps:
- template: templates/build-steps.yaml

- job: Run_e2e_tests
displayName: "Run e2e tests"
condition: succeeded()
timeoutInMinutes: 120
workspace:
clean: all

pool:
vmImage: ubuntu-latest

variables:
- group: "viewer-components-react e2e tests env"

steps:
- template: templates/e2e-steps.yaml

- job: Check_change_files
displayName: "Check change files"
condition: succeeded()
Expand Down
36 changes: 0 additions & 36 deletions .pipelines/templates/e2e-steps.yaml

This file was deleted.

11 changes: 3 additions & 8 deletions apps/test-viewer/.env.template
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,16 @@
IMJS_AUTH_CLIENT_CLIENT_ID = ""
IMJS_AUTH_CLIENT_REDIRECT_URI = "http://localhost:3000/signin-callback"
IMJS_AUTH_CLIENT_LOGOUT_URI = "http://localhost:3000"
IMJS_AUTH_CLIENT_SCOPES = "imodelaccess:read imodels:read realitydata:read"
IMJS_AUTH_CLIENT_SCOPES = "itwin-platform"
IMJS_AUTH_AUTHORITY = "https://ims.bentley.com"

# Optional identifiers of the iModel that should be opened by default. If not specified,
# they can be supplied to a running application through URL parameters.
# they can be supplied to a running application through URL parameters `iTwinId`` and `iModelId`.
IMJS_ITWIN_ID = ""
IMJS_IMODEL_ID = ""

# Optional user credentials to access imodel referenced by IMJS_ITWIN_ID and IMJS_IMODEL_ID.
# If not specified, the app will request you to login.
IMJS_USER_EMAIL = ""
IMJS_USER_PASSWORD = ""

# Space separated ids of widgets that should be added to viewer UI
# Supported widget: 'tree-widget', 'property-grid'
# See `src/UiProvidersConfig.tsx` for available widget names
IMJS_ENABLED_WIDGETS = "tree-widget property-grid measure-tools"

# Enable hot reloading. Might have performance impact on first load.
Expand Down
2 changes: 1 addition & 1 deletion apps/test-viewer/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
/coverage

# production
/build
/dist

# misc
.DS_Store
Expand Down
20 changes: 10 additions & 10 deletions apps/test-viewer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,14 @@ In order to restore hot reloading for workspace packages [`linkWorkspaceDeps.js`

### Enabling/disabling widgets

This app has ability to enable/disable predefined widgets through environment variable. [`IMJS_ENABLED_WIDGETS`](.env.template) variable can be used to specify a list of widgets that should be added to viewer. Widgets supported by this variable are configured in [`UiProvidersConfig.ts`](./src/UiProvidersConfig.ts#L46).
This app has ability to enable/disable predefined widgets. There are two ways to achieve this (in the order of precedence):

1. Using the `widgets` URL parameter, e.g.: `widgets=tree-widget;property-grid`.
2. Using the `IMJS_ENABLED_WIDGETS` environment variable, that can be set to a space-separated list of widget names, e.g.: `IMJS_ENABLED_WIDGETS=tree-widget property-grid`.

Consult [`UiProvidersConfig.tsx`](./src/UiProvidersConfig.tsx#L46) for widget names that can be used to enable/disable widgets.

If enabled widgets are not specified in either of the above ways, all widgets will be enabled by default.

## Environment Variables

Expand All @@ -31,19 +38,12 @@ Prior to running the app, you will need to add OIDC client configuration to the
IMJS_AUTH_CLIENT_CLIENT_ID=""
IMJS_AUTH_CLIENT_REDIRECT_URI = "http://localhost:3000/signin-callback"
IMJS_AUTH_CLIENT_LOGOUT_URI = "http://localhost:3000"
IMJS_AUTH_CLIENT_SCOPES = "imodelaccess:read imodels:read realitydata:read"
IMJS_AUTH_CLIENT_SCOPES = "itwin-platform"
```

- You can generate a [test client](https://developer.bentley.com/tutorials/web-application-quick-start/#2-register-an-application) to get started.

- Scopes expected by the viewer are:

- **Visualization**: `imodelaccess:read`
- **iModels**: `imodels:read`
- **Reality Data**: `realitydata:read`

- The client must support the `itwin-platform` scope.
- The application will use the path of the redirect URI to handle the redirection, it must simply match what is defined in your client.

- When you are ready to build a production application, [register here](https://developer.bentley.com/register/).

You should also add a valid iTwinId and iModelId for your user in the this file:
Expand Down
48 changes: 48 additions & 0 deletions apps/test-viewer/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
const iTwinPlugin = require("@itwin/eslint-plugin");
const reactPlugin = require("eslint-plugin-react");
const eslintConfigPrettier = require("eslint-config-prettier");
const unusedImports = require("eslint-plugin-unused-imports");

module.exports = [
{
files: ["**/*.{ts,tsx}"],
...iTwinPlugin.configs.uiConfig,
rules: {
...iTwinPlugin.configs.uiConfig.rules,
"@itwin/no-internal": ["error"],
},
},
{
files: ["**/*.{ts,tsx}"],
rules: {
...reactPlugin.configs["jsx-runtime"].rules,
},
},
{
plugins: {
"unused-imports": unusedImports,
},
files: ["**/*.{ts,tsx}"],
rules: {
"no-duplicate-imports": "off",
"import/no-duplicates": "error",
"object-curly-spacing": ["error", "always"],
"@typescript-eslint/consistent-type-imports": "error",
"@typescript-eslint/no-unused-vars": "off",
"unused-imports/no-unused-imports": "error",
"unused-imports/no-unused-vars": ["error", { vars: "all", varsIgnorePattern: "^_", args: "after-used", argsIgnorePattern: "^_" }],
curly: ["error", "all"],
},
},
eslintConfigPrettier,
{
files: ["**/*.{ts,tsx}"],
rules: {
"no-console": "off",
},
},
];
Loading

0 comments on commit afbd086

Please sign in to comment.