From 4070f6f1ea88cdb773ddaa7079a7a24f8f0c012d Mon Sep 17 00:00:00 2001 From: Sean Fong Date: Mon, 10 Jun 2024 21:47:53 +0930 Subject: [PATCH 01/10] Rewrite existing cypress tests in Playwright --- .github/workflows/main.yml | 24 +++++++ apps/smart-forms-app/.gitignore | 6 +- apps/smart-forms-app/e2e/_pre-run.spec.ts | 70 +++++++++++++++++++ apps/smart-forms-app/e2e/dashboard.spec.ts | 56 ++++++++++++++++ apps/smart-forms-app/e2e/globals.ts | 21 ++++++ apps/smart-forms-app/e2e/saving.spec.ts | 76 +++++++++++++++++++++ apps/smart-forms-app/package.json | 1 + apps/smart-forms-app/playwright.config.ts | 78 ++++++++++++++++++++++ package-lock.json | 60 +++++++++++++++++ 9 files changed, 391 insertions(+), 1 deletion(-) create mode 100644 apps/smart-forms-app/e2e/_pre-run.spec.ts create mode 100644 apps/smart-forms-app/e2e/dashboard.spec.ts create mode 100644 apps/smart-forms-app/e2e/globals.ts create mode 100644 apps/smart-forms-app/e2e/saving.spec.ts create mode 100644 apps/smart-forms-app/playwright.config.ts diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index bd0151710..6ff86c3ad 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -52,6 +52,30 @@ jobs: CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + playwright-test: + timeout-minutes: 60 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 16 + cache: npm + - name: Install dependencies + run: npm ci + - name: Install Playwright Browsers + run: npx playwright install --with-deps + - name: Run Playwright tests + run: npx playwright test + - uses: actions/upload-artifact@v4 + if: always() + with: + build: npm run build -w apps/smart-forms-app + start: npm run preview -w apps/smart-forms-app + name: playwright-report + path: playwright-report/ + retention-days: 30 + lint: name: Lint runs-on: ubuntu-latest diff --git a/apps/smart-forms-app/.gitignore b/apps/smart-forms-app/.gitignore index 6e5a38b01..2f0fb72ee 100644 --- a/apps/smart-forms-app/.gitignore +++ b/apps/smart-forms-app/.gitignore @@ -26,4 +26,8 @@ yarn-error.log* # cypress non-test files cypress/screenshots cypress/videos -temp \ No newline at end of file +temp +/test-results/ +/playwright-report/ +/blob-report/ +/playwright/.cache/ diff --git a/apps/smart-forms-app/e2e/_pre-run.spec.ts b/apps/smart-forms-app/e2e/_pre-run.spec.ts new file mode 100644 index 000000000..ca455639a --- /dev/null +++ b/apps/smart-forms-app/e2e/_pre-run.spec.ts @@ -0,0 +1,70 @@ +/* + * Copyright 2024 Commonwealth Scientific and Industrial Research + * Organisation (CSIRO) ABN 41 687 119 230. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { expect, test } from '@playwright/test'; +import { PLAYWRIGHT_APP_URL, PLAYWRIGHT_EHR_URL, PLAYWRIGHT_FORMS_SERVER_URL } from './globals'; + +test('launch without questionnaire context, select a questionnaire and create a new response', async ({ + page +}) => { + // Launch app without questionnaire context + const fetchQPromise = page.waitForResponse( + `${PLAYWRIGHT_FORMS_SERVER_URL}/Questionnaire?_count=100&_sort=-date&` + ); + const launchUrl = `${PLAYWRIGHT_APP_URL}/launch?iss=https%3A%2F%2Fproxy.smartforms.io%2Fv%2Fr4%2Ffhir&launch=WzAsInBhdC1zZiIsInByaW1hcnktcGV0ZXIiLCJBVVRPIiwwLDAsMCwiZmhpclVzZXIgb25saW5lX2FjY2VzcyBvcGVuaWQgcHJvZmlsZSBwYXRpZW50L0NvbmRpdGlvbi5ycyBwYXRpZW50L09ic2VydmF0aW9uLnJzIGxhdW5jaCBwYXRpZW50L0VuY291bnRlci5ycyBwYXRpZW50L1F1ZXN0aW9ubmFpcmVSZXNwb25zZS5jcnVkcyBwYXRpZW50L1BhdGllbnQucnMiLCJodHRwOi8vbG9jYWxob3N0OjQxNzMvIiwiYTU3ZDkwZTMtNWY2OS00YjkyLWFhMmUtMjk5MjE4MDg2M2MxIiwiIiwiIiwiIiwiIiwwLDEsIiIsZmFsc2Vd`; + await page.goto(launchUrl); + expect((await fetchQPromise).status()).toBe(200); + + // Search MBS715 title + const fetchQByTitlePromise = page.waitForResponse( + `${PLAYWRIGHT_FORMS_SERVER_URL}/Questionnaire?_count=100&_sort=-date&title:contains=Aboriginal%20and%20Torres%20Strait%20Islander%20Health%20Check` + ); + await page + .getByTestId('search-field-questionnaires') + .locator('input') + .fill('Aboriginal and Torres Strait Islander Health Check'); + await fetchQByTitlePromise; + + // Open first MBS715 questionnaire + const populatePromise = page.waitForResponse( + new RegExp(/^https:\/\/proxy\.smartforms\.io\/v\/r4\/fhir\/(Observation|Condition)\?.+$/) + ); + await page + .getByTestId('questionnaire-list-row') + .getByText('Aboriginal and Torres Strait Islander Health Check') + .first() + .click(); + await page.getByTestId('button-create-response').click(); + expect((await populatePromise).status()).toBe(200); + + // Test radio item + await expect(page.getByTestId('q-item-choice-radio-answer-value-set-box')).toContainText( + 'Eligible for health check' + ); + await page.getByTestId('q-item-choice-radio-answer-value-set-box').first().click(); + await expect(page.getByTestId('updating-indicator')).toBeInViewport(); + + // Save progress + const savePromise = page.waitForResponse(`${PLAYWRIGHT_EHR_URL}/QuestionnaireResponse`); + await page.getByTestId('renderer-operation-item').getByText('Save Progress').click(); + const saveResponse = await savePromise; + expect(saveResponse.status()).toBe(201); + await expect(page.getByText('Response saved')).toBeInViewport(); + + // Go back to questionnaires + await page.getByTestId('renderer-operation-item').getByText('Back to Questionnaires').click(); +}); diff --git a/apps/smart-forms-app/e2e/dashboard.spec.ts b/apps/smart-forms-app/e2e/dashboard.spec.ts new file mode 100644 index 000000000..213772438 --- /dev/null +++ b/apps/smart-forms-app/e2e/dashboard.spec.ts @@ -0,0 +1,56 @@ +/* + * Copyright 2024 Commonwealth Scientific and Industrial Research + * Organisation (CSIRO) ABN 41 687 119 230. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { expect, test } from '@playwright/test'; +import { PLAYWRIGHT_APP_URL, PLAYWRIGHT_FORMS_SERVER_URL } from './globals'; + +const questionnaireTitle = 'Aboriginal and Torres Strait Islander Health Check'; + +test.beforeEach(async ({ page }) => { + // Launch app without questionnaire context + const fetchQPromise = page.waitForResponse( + `${PLAYWRIGHT_FORMS_SERVER_URL}/Questionnaire?_count=100&_sort=-date&` + ); + const launchUrl = `${PLAYWRIGHT_APP_URL}/launch?iss=https%3A%2F%2Fproxy.smartforms.io%2Fv%2Fr4%2Ffhir&launch=WzAsInBhdC1zZiIsInByaW1hcnktcGV0ZXIiLCJBVVRPIiwwLDAsMCwiZmhpclVzZXIgb25saW5lX2FjY2VzcyBvcGVuaWQgcHJvZmlsZSBwYXRpZW50L0NvbmRpdGlvbi5ycyBwYXRpZW50L09ic2VydmF0aW9uLnJzIGxhdW5jaCBwYXRpZW50L0VuY291bnRlci5ycyBwYXRpZW50L1F1ZXN0aW9ubmFpcmVSZXNwb25zZS5jcnVkcyBwYXRpZW50L1BhdGllbnQucnMiLCJodHRwOi8vbG9jYWxob3N0OjQxNzMvIiwiYTU3ZDkwZTMtNWY2OS00YjkyLWFhMmUtMjk5MjE4MDg2M2MxIiwiIiwiIiwiIiwiIiwwLDEsIiIsZmFsc2Vd`; + await page.goto(launchUrl); + expect((await fetchQPromise).status()).toBe(200); + + // Wait for responses to load + const fetchQRPromise = page.waitForResponse( + new RegExp(/^https:\/\/proxy\.smartforms\.io\/v\/r4\/fhir\/QuestionnaireResponse\?.+$/) + ); + await page.getByTestId('questionnaire-list-row').getByText(questionnaireTitle).first().click(); + const fetchQRResponse = await fetchQRPromise; + expect(fetchQRResponse.status()).toBe(200); +}); + +test('View response from MBS715', async ({ page }) => { + await expect(page.getByTestId('button-view-responses')).toBeEnabled(); + await page.getByTestId('button-view-responses').click(); + + // Open responses page + await expect(page.getByTestId('responses-list-toolbar')).toContainText(questionnaireTitle); + await page.getByTestId('response-list-row').getByText(questionnaireTitle).first().click(); + + // Open response + await expect(page.getByTestId('button-open-response')).toBeEnabled(); + await page.getByTestId('button-open-response').click(); + + // + await expect(page).toHaveURL(`${PLAYWRIGHT_APP_URL}/viewer`); + await expect(page.getByTestId('response-preview-box')).toContainText(questionnaireTitle); +}); diff --git a/apps/smart-forms-app/e2e/globals.ts b/apps/smart-forms-app/e2e/globals.ts new file mode 100644 index 000000000..6f702bde6 --- /dev/null +++ b/apps/smart-forms-app/e2e/globals.ts @@ -0,0 +1,21 @@ +/* + * Copyright 2024 Commonwealth Scientific and Industrial Research + * Organisation (CSIRO) ABN 41 687 119 230. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export const PLAYWRIGHT_EHR_URL = 'https://proxy.smartforms.io/v/r4/fhir'; +export const PLAYWRIGHT_FORMS_SERVER_URL = 'https://smartforms.csiro.au/api/fhir'; + +export const PLAYWRIGHT_APP_URL = 'http://localhost:4173'; diff --git a/apps/smart-forms-app/e2e/saving.spec.ts b/apps/smart-forms-app/e2e/saving.spec.ts new file mode 100644 index 000000000..5079dac8f --- /dev/null +++ b/apps/smart-forms-app/e2e/saving.spec.ts @@ -0,0 +1,76 @@ +/* + * Copyright 2024 Commonwealth Scientific and Industrial Research + * Organisation (CSIRO) ABN 41 687 119 230. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { expect, test } from '@playwright/test'; +import { PLAYWRIGHT_APP_URL, PLAYWRIGHT_EHR_URL } from './globals'; + +const questionnaireTitle = 'Aboriginal and Torres Strait Islander Health Check'; + +test.beforeEach(async ({ page }) => { + // Open first MBS715 questionnaire via launch context + const populatePromise = page.waitForResponse( + new RegExp(/^https:\/\/proxy\.smartforms\.io\/v\/r4\/fhir\/(Observation|Condition)\?.+$/) + ); + const launchUrl = `${PLAYWRIGHT_APP_URL}/launch?iss=https%3A%2F%2Fproxy.smartforms.io%2Fv%2Fr4%2Ffhir&launch=WzAsInBhdC1zZiIsInByaW1hcnktcGV0ZXIiLCJBVVRPIiwwLDAsMCwiZmhpclVzZXIgb25saW5lX2FjY2VzcyBvcGVuaWQgcHJvZmlsZSBwYXRpZW50L0NvbmRpdGlvbi5ycyBwYXRpZW50L09ic2VydmF0aW9uLnJzIGxhdW5jaCBwYXRpZW50L0VuY291bnRlci5ycyBwYXRpZW50L1F1ZXN0aW9ubmFpcmVSZXNwb25zZS5jcnVkcyBwYXRpZW50L1BhdGllbnQucnMiLCJodHRwOi8vbG9jYWxob3N0OjQxNzMvIiwiYTU3ZDkwZTMtNWY2OS00YjkyLWFhMmUtMjk5MjE4MDg2M2MxIiwiIiwiIiwiIiwiIiwwLDEsIntcInJvbGVcIjpcInF1ZXN0aW9ubmFpcmUtcmVuZGVyLW9uLWxhdW5jaFwiLFwiY2Fub25pY2FsXCI6XCJodHRwOi8vd3d3LmhlYWx0aC5nb3YuYXUvYXNzZXNzbWVudHMvbWJzLzcxNXwwLjEuMC1hc3NlbWJsZWRcIixcInR5cGVcIjpcIlF1ZXN0aW9ubmFpcmVcIn0iLGZhbHNlXQ`; + await page.goto(launchUrl); + const populateResponse = await populatePromise; + expect(populateResponse.status()).toBe(200); +}); + +test('Saving a response as draft then final', async ({ page }) => { + // Go to Consent tab and click on a boolean item + await page + .getByTestId('renderer-tab-list') + .locator('.MuiButtonBase-root') + .getByText('Consent') + .click(); + await page.getByTestId('q-item-boolean-box').first().locator('input').first().click(); + + // Save as draft + const saveDraftPromise = page.waitForResponse(`${PLAYWRIGHT_EHR_URL}/QuestionnaireResponse`); + await page.getByTestId('renderer-operation-item').getByText('Save Progress').click(); + const saveDraftResponse = await saveDraftPromise; + expect(saveDraftResponse.status()).toBe(201); + await expect(page.getByText('Response saved')).toBeInViewport(); + + // Select response in responses page + await page.getByTestId('renderer-operation-item').getByText('View Existing Responses').click(); + await page.getByTestId('response-list-row').getByText('in-progress').first().click(); + await expect(page.getByTestId('button-open-response')).toBeEnabled(); + await page.getByTestId('button-open-response').click(); + + // View response in viewer + await expect(page).toHaveURL(`${PLAYWRIGHT_APP_URL}/viewer`); + await expect(page.getByTestId('response-preview-box')).toContainText( + 'Aboriginal and Torres Strait Islander Health Check' + ); + + // Re-open the response + await page.getByTestId('renderer-operation-item').getByText('Edit Response').click(); + await expect(page).toHaveURL(`${PLAYWRIGHT_APP_URL}/renderer`); + + // Save as final + const saveFinalPromise = page.waitForResponse((response) => + response.url().startsWith(`${PLAYWRIGHT_EHR_URL}/QuestionnaireResponse/`) + ); + await page.getByTestId('renderer-operation-item').getByText('Save as Final').click(); + await page.getByTestId('save-as-final-button').click(); + const saveFinalResponse = await saveFinalPromise; + expect(saveFinalResponse.status()).toBe(200); + await expect(page.getByText('Response saved as final')).toBeInViewport(); + await expect(page).toHaveURL(`${PLAYWRIGHT_APP_URL}/dashboard/existing`); +}); diff --git a/apps/smart-forms-app/package.json b/apps/smart-forms-app/package.json index e99005b46..e56198e5b 100644 --- a/apps/smart-forms-app/package.json +++ b/apps/smart-forms-app/package.json @@ -77,6 +77,7 @@ }, "devDependencies": { "@jest/globals": "^29.5.0", + "@playwright/test": "^1.44.1", "@sentry/cli": "^2.20.6", "@storybook/addon-essentials": "^8.0.6", "@storybook/addon-interactions": "^7.4.6", diff --git a/apps/smart-forms-app/playwright.config.ts b/apps/smart-forms-app/playwright.config.ts new file mode 100644 index 000000000..611b1a7e3 --- /dev/null +++ b/apps/smart-forms-app/playwright.config.ts @@ -0,0 +1,78 @@ +import { defineConfig, devices } from '@playwright/test'; + +/** + * Read environment variables from file. + * https://github.com/motdotla/dotenv + */ +// require('dotenv').config(); + +/** + * See https://playwright.dev/docs/test-configuration. + */ +export default defineConfig({ + testDir: './e2e', + /* Run tests in files in parallel */ + fullyParallel: true, + /* Fail the build on CI if you accidentally left test.only in the source code. */ + forbidOnly: !!process.env.CI, + /* Retry on CI only */ + retries: process.env.CI ? 2 : 0, + /* Opt out of parallel tests on CI. */ + workers: process.env.CI ? 1 : undefined, + /* Reporter to use. See https://playwright.dev/docs/test-reporters */ + reporter: 'html', + /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ + use: { + /* Base URL to use in actions like `await page.goto('/')`. */ + // baseURL: 'http://127.0.0.1:3000', + + /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ + trace: 'on-first-retry', + testIdAttribute: 'data-test' + }, + + /* Configure projects for major browsers */ + projects: [ + { + name: 'chromium', + use: { ...devices['Desktop Chrome'] } + }, + + { + name: 'firefox', + use: { ...devices['Desktop Firefox'] } + }, + + { + name: 'webkit', + use: { ...devices['Desktop Safari'] } + } + + /* Test against mobile viewports. */ + // { + // name: 'Mobile Chrome', + // use: { ...devices['Pixel 5'] }, + // }, + // { + // name: 'Mobile Safari', + // use: { ...devices['iPhone 12'] }, + // }, + + /* Test against branded browsers. */ + // { + // name: 'Microsoft Edge', + // use: { ...devices['Desktop Edge'], channel: 'msedge' }, + // }, + // { + // name: 'Google Chrome', + // use: { ...devices['Desktop Chrome'], channel: 'chrome' }, + // }, + ], + + /* Run your local dev server before starting the tests */ + webServer: { + command: 'npm run start', + url: 'http://localhost:4173', + reuseExistingServer: !process.env.CI + } +}); diff --git a/package-lock.json b/package-lock.json index 6590f1ded..0b8c932fa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -101,6 +101,7 @@ }, "devDependencies": { "@jest/globals": "^29.5.0", + "@playwright/test": "^1.44.1", "@sentry/cli": "^2.20.6", "@storybook/addon-essentials": "^8.0.6", "@storybook/addon-interactions": "^7.4.6", @@ -6447,6 +6448,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@playwright/test": { + "version": "1.44.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.44.1.tgz", + "integrity": "sha512-1hZ4TNvD5z9VuhNJ/walIjvMVvYkZKf71axoF/uiAqpntQJXpG64dlXhoDXE3OczPuTuvjf/M5KWFg5VAVUS3Q==", + "dev": true, + "dependencies": { + "playwright": "1.44.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/@pnpm/config.env-replace": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", @@ -35523,6 +35539,50 @@ "node": ">=4" } }, + "node_modules/playwright": { + "version": "1.44.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.44.1.tgz", + "integrity": "sha512-qr/0UJ5CFAtloI3avF95Y0L1xQo6r3LQArLIg/z/PoGJ6xa+EwzrwO5lpNr/09STxdHuUoP2mvuELJS+hLdtgg==", + "dev": true, + "dependencies": { + "playwright-core": "1.44.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=16" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.44.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.44.1.tgz", + "integrity": "sha512-wh0JWtYTrhv1+OSsLPgFzGzt67Y7BE/ZS3jEqgGBlp2ppp1ZDj8c+9IARNW4dwf1poq5MgHreEM2KV/GuR4cFA==", + "dev": true, + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/playwright/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/polished": { "version": "4.2.2", "dev": true, From 891410ea7652e9de78ef803b9c1c461f85d0d34f Mon Sep 17 00:00:00 2001 From: Sean Fong Date: Tue, 11 Jun 2024 11:39:34 +0930 Subject: [PATCH 02/10] Add bit of everything to standalone tester --- .../QuestionnaireListToolbarButtons.tsx | 3 - .../components/StandalonePropsPicker.tsx | 30 +- .../standalone/data/QBitOfEverything.json | 267 ++++++++++++++++++ .../standalone/utils/standaloneList.ts | 9 + 4 files changed, 292 insertions(+), 17 deletions(-) create mode 100644 apps/smart-forms-app/src/features/standalone/data/QBitOfEverything.json diff --git a/apps/smart-forms-app/src/features/dashboard/components/DashboardPages/QuestionnairePage/TableComponents/QuestionnaireListToolbarButtons.tsx b/apps/smart-forms-app/src/features/dashboard/components/DashboardPages/QuestionnairePage/TableComponents/QuestionnaireListToolbarButtons.tsx index 8f7e6ee38..66de10fca 100644 --- a/apps/smart-forms-app/src/features/dashboard/components/DashboardPages/QuestionnairePage/TableComponents/QuestionnaireListToolbarButtons.tsx +++ b/apps/smart-forms-app/src/features/dashboard/components/DashboardPages/QuestionnairePage/TableComponents/QuestionnaireListToolbarButtons.tsx @@ -35,9 +35,6 @@ function QuestionnaireListToolbarButtons(props: QuestionnaireListToolbarButtonsP const isNotLaunched = !smartClient; - console.log(isNotLaunched); - console.log(debugModeEnabled); - return ( {isNotLaunched && debugModeEnabled ? : null} diff --git a/apps/smart-forms-app/src/features/standalone/components/StandalonePropsPicker.tsx b/apps/smart-forms-app/src/features/standalone/components/StandalonePropsPicker.tsx index 86f1bcdce..f55c39206 100644 --- a/apps/smart-forms-app/src/features/standalone/components/StandalonePropsPicker.tsx +++ b/apps/smart-forms-app/src/features/standalone/components/StandalonePropsPicker.tsx @@ -58,20 +58,22 @@ function StandalonePropsPicker(props: StandalonePropsPickerProps) { control={} label="Questionnaire" /> - { - dispatch({ - type: 'SET_RESPONSE', - payload: state.response ? null : rendererPropsSingle.response - }); - }} - /> - } - label="Questionnaire response" - /> + {rendererPropsSingle.response ? ( + { + dispatch({ + type: 'SET_RESPONSE', + payload: state.response ? null : rendererPropsSingle.response + }); + }} + /> + } + label="Questionnaire response" + /> + ) : null} {rendererPropsSingle.additionalVars ? ( \n Bit of everything\n
\n Status: Active\n
\n Publisher: DEMO: Telstra Health\n " + }, + "extension": [ + { + "url": "http://hl7.org/fhir/StructureDefinition/terminology-server", + "valueUrl": "https://sqlonfhir-r4.azurewebsites.net/fhir" + } + ], + "url": "http://fhir.telstrahealth.com/fast-forms/Questionnaire/bit-of-everything", + "name": "BitOfEverything", + "title": "Bit of everything", + "status": "active", + "date": "2021-06-14", + "publisher": "DEMO: Telstra Health", + "useContext": [ + { + "code": { + "system": "http://terminology.hl7.org/CodeSystem/usage-context-type", + "code": "user", + "display": "User Type" + }, + "valueCodeableConcept": { + "coding": [ + { + "code": "demo", + "display": "Demonstration" + } + ] + } + } + ], + "item": [ + { + "extension": [ + { + "url": "http://hl7.org/fhir/StructureDefinition/terminology-server", + "valueUrl": "https://sqlonfhir-r4.azurewebsites.net/fhir" + } + ], + "linkId": "root", + "text": "Bit of Everything", + "type": "group", + "item": [ + { + "linkId": "Item-label", + "text": "display label", + "type": "display" + }, + { + "linkId": "Item-string", + "text": "string", + "type": "string" + }, + { + "extension": [ + { + "url": "http://standards.healthconnex.com.au/fhir/StructureDefinition/Questionnaire-TextArea-Row", + "valueInteger": 10 + } + ], + "linkId": "Item-text", + "text": "text", + "type": "text" + }, + { + "linkId": "Item-bool", + "code": [ + { + "code": "true" + } + ], + "text": "boolean", + "type": "boolean" + }, + { + "linkId": "Item-date", + "text": "date", + "type": "date" + }, + { + "linkId": "Item-datetime", + "text": "datetime", + "type": "dateTime" + }, + { + "linkId": "Item-time", + "text": "time", + "type": "time" + }, + { + "linkId": "Item-integer", + "text": "integer", + "type": "integer" + }, + { + "extension": [ + { + "url": "http://hl7.org/fhir/StructureDefinition/questionnaire-unit", + "valueCoding": { + "system": "http://unitsofmeasure.org", + "code": "m", + "display": "meters" + } + } + ], + "linkId": "Item-decimal", + "text": "decimal", + "type": "decimal" + }, + { + "linkId": "Item-url", + "text": "url", + "type": "url" + }, + { + "linkId": "Item-reference", + "text": "reference", + "type": "reference" + }, + { + "extension": [ + { + "url": "http://hl7.org/fhir/StructureDefinition/mimeType", + "valueCode": "image/png" + }, + { + "url": "http://hl7.org/fhir/StructureDefinition/mimeType", + "valueCode": "image/jpeg" + }, + { + "url": "http://hl7.org/fhir/StructureDefinition/mimeType", + "valueCode": "application/json" + }, + { + "url": "http://hl7.org/fhir/StructureDefinition/mimeType", + "valueCode": "application/pdf" + }, + { + "url": "http://hl7.org/fhir/StructureDefinition/maxSize", + "valueDecimal": 1000000 + } + ], + "linkId": "Item-attachment", + "text": "attachment", + "type": "attachment" + }, + { + "extension": [ + { + "url": "http://hl7.org/fhir/StructureDefinition/questionnaire-unitOption", + "valueCoding": { + "system": "http://unitsofmeasure.org", + "code": "m", + "display": "meters" + } + }, + { + "url": "http://hl7.org/fhir/StructureDefinition/questionnaire-unitOption", + "valueCoding": { + "system": "http://unitsofmeasure.org", + "code": "cm", + "display": "centimeters" + } + } + ], + "linkId": "Item-quantity", + "text": "quantity", + "type": "quantity" + }, + { + "linkId": "Item-rb-local", + "text": "radiobuttons (answerOptions)", + "type": "choice", + "repeats": false, + "answerOption": [ + { + "valueCoding": { + "system": "http://example.org/coding-test", + "code": "a", + "display": "option A" + } + }, + { + "valueCoding": { + "system": "http://example.org/coding-test", + "code": "b", + "display": "option B" + } + } + ] + }, + { + "linkId": "Item-rb", + "text": "radiobuttons (answerValueSet)", + "type": "choice", + "repeats": false, + "answerValueSet": "http://fhir.telstrahealth.com.au/tcm/ValueSet/ARE" + }, + { + "extension": [ + { + "url": "http://hl7.org/fhir/StructureDefinition/questionnaire-itemControl", + "valueCodeableConcept": { + "coding": [ + { + "system": "http://hl7.org/fhir/questionnaire-item-control", + "code": "drop-down" + } + ] + } + } + ], + "linkId": "Item10", + "text": "drop-down (answerValueSet)", + "type": "choice", + "repeats": false, + "answerValueSet": "http://fhir.telstrahealth.com.au/tcm/ValueSet/ARE" + }, + { + "extension": [ + { + "url": "http://hl7.org/fhir/StructureDefinition/questionnaire-itemControl", + "valueCodeableConcept": { + "coding": [ + { + "system": "http://hl7.org/fhir/questionnaire-item-control", + "code": "autocomplete" + } + ] + } + } + ], + "linkId": "Item11", + "text": "autocomplete (countries)", + "type": "choice", + "repeats": false, + "answerValueSet": "http://fhir.telstrahealth.com.au/tcm/ValueSet/COU" + }, + { + "extension": [ + { + "url": "http://hl7.org/fhir/StructureDefinition/questionnaire-itemControl", + "valueCodeableConcept": { + "coding": [ + { + "system": "http://hl7.org/fhir/questionnaire-item-control", + "code": "autocomplete" + } + ] + } + } + ], + "linkId": "Item12", + "text": "open-choice (countries)", + "type": "open-choice", + "repeats": false, + "answerValueSet": "http://fhir.telstrahealth.com.au/tcm/ValueSet/COU" + } + ] + } + ] +} diff --git a/apps/smart-forms-app/src/features/standalone/utils/standaloneList.ts b/apps/smart-forms-app/src/features/standalone/utils/standaloneList.ts index a9635798f..d67e3dafe 100644 --- a/apps/smart-forms-app/src/features/standalone/utils/standaloneList.ts +++ b/apps/smart-forms-app/src/features/standalone/utils/standaloneList.ts @@ -26,6 +26,7 @@ import QCVDRiskJson from '../data/QCVDRisk.json'; import RCVDRiskJson from '../data/RCVDRisk.json'; import QDemoAnsExp from '../data/QDemoAnsExp.json'; import RDemoAnsExp from '../data/RDemoAnsExp.json'; +import QBitOfEverything from '../data/QBitOfEverything.json'; export const rendererPropsList: RendererPropsState[] = [ { @@ -59,5 +60,13 @@ export const rendererPropsList: RendererPropsState[] = [ additionalVars: null, terminologyServerUrl: 'http://hapi.fhir.org/baseR4', readOnly: false + }, + { + id: 'BitOfEverything', + questionnaire: QBitOfEverything as Questionnaire, + response: null, + additionalVars: null, + terminologyServerUrl: 'https://sqlonfhir-r4.azurewebsites.net/fhir', + readOnly: false } ]; From a56563aee42604299144bbd6a68429bd92c9b0b9 Mon Sep 17 00:00:00 2001 From: Sean Fong Date: Tue, 11 Jun 2024 11:50:35 +0930 Subject: [PATCH 03/10] Tweak playwright ci #1 --- .github/workflows/main.yml | 3 ++- apps/smart-forms-app/package.json | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6ff86c3ad..b9e5ba7b9 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -53,6 +53,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} playwright-test: + name: Playwright Tests timeout-minutes: 60 runs-on: ubuntu-latest steps: @@ -66,7 +67,7 @@ jobs: - name: Install Playwright Browsers run: npx playwright install --with-deps - name: Run Playwright tests - run: npx playwright test + run: npm run playwright -w apps/smart-forms-app - uses: actions/upload-artifact@v4 if: always() with: diff --git a/apps/smart-forms-app/package.json b/apps/smart-forms-app/package.json index 2290c0248..9aec525a6 100644 --- a/apps/smart-forms-app/package.json +++ b/apps/smart-forms-app/package.json @@ -12,7 +12,9 @@ "preview": "vite preview --port 4173", "cypress": "cypress open", "storybook": "storybook dev -p 6006", - "build-storybook": "storybook build" + "build-storybook": "storybook build", + "playwright": "npx playwright test", + "playwright-ui": "npx playwright test --ui" }, "repository": { "type": "git", From 786fd0663a5d68d71039c21d68bf764aec1cb9f8 Mon Sep 17 00:00:00 2001 From: Sean Fong Date: Tue, 11 Jun 2024 11:55:24 +0930 Subject: [PATCH 04/10] Tweak playwright ci #2 --- apps/smart-forms-app/playwright.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/smart-forms-app/playwright.config.ts b/apps/smart-forms-app/playwright.config.ts index 611b1a7e3..84c2031f3 100644 --- a/apps/smart-forms-app/playwright.config.ts +++ b/apps/smart-forms-app/playwright.config.ts @@ -71,7 +71,7 @@ export default defineConfig({ /* Run your local dev server before starting the tests */ webServer: { - command: 'npm run start', + command: 'npm run build && npm run preview', url: 'http://localhost:4173', reuseExistingServer: !process.env.CI } From 2a4d944e74fbedb6710ac84f26fb7576491b4f44 Mon Sep 17 00:00:00 2001 From: Sean Fong Date: Tue, 11 Jun 2024 13:26:29 +0930 Subject: [PATCH 05/10] Add readOnly attributes to attachment field --- apps/smart-forms-app/e2e/saving.spec.ts | 4 +--- .../AttachmentItem/AttachmentField.tsx | 9 ++++++--- .../AttachmentItem/AttachmentFileCollector.tsx | 12 +++++++++--- .../AttachmentItem/AttachmentFileDropBox.tsx | 10 +++++++--- .../AttachmentItem/AttachmentUrlField.tsx | 4 +++- 5 files changed, 26 insertions(+), 13 deletions(-) diff --git a/apps/smart-forms-app/e2e/saving.spec.ts b/apps/smart-forms-app/e2e/saving.spec.ts index 5079dac8f..48b7e5b32 100644 --- a/apps/smart-forms-app/e2e/saving.spec.ts +++ b/apps/smart-forms-app/e2e/saving.spec.ts @@ -55,9 +55,7 @@ test('Saving a response as draft then final', async ({ page }) => { // View response in viewer await expect(page).toHaveURL(`${PLAYWRIGHT_APP_URL}/viewer`); - await expect(page.getByTestId('response-preview-box')).toContainText( - 'Aboriginal and Torres Strait Islander Health Check' - ); + await expect(page.getByTestId('response-preview-box')).toContainText(questionnaireTitle); // Re-open the response await page.getByTestId('renderer-operation-item').getByText('Edit Response').click(); diff --git a/packages/smart-forms-renderer/src/components/FormComponents/AttachmentItem/AttachmentField.tsx b/packages/smart-forms-renderer/src/components/FormComponents/AttachmentItem/AttachmentField.tsx index 31d265722..79408a8e3 100644 --- a/packages/smart-forms-renderer/src/components/FormComponents/AttachmentItem/AttachmentField.tsx +++ b/packages/smart-forms-renderer/src/components/FormComponents/AttachmentItem/AttachmentField.tsx @@ -50,12 +50,13 @@ function AttachmentField(props: AttachmentFieldProps) { return ( <> - + An attachment must either have a file or a URL, or both. @@ -70,7 +71,9 @@ function AttachmentField(props: AttachmentFieldProps) { /> - File name (optional) + + File name (optional) + {uploadedFile && url ? ( - + Ensure that the attached file and URL has the same content. ) : null} diff --git a/packages/smart-forms-renderer/src/components/FormComponents/AttachmentItem/AttachmentFileCollector.tsx b/packages/smart-forms-renderer/src/components/FormComponents/AttachmentItem/AttachmentFileCollector.tsx index 9bbcd4b44..e3228fb62 100644 --- a/packages/smart-forms-renderer/src/components/FormComponents/AttachmentItem/AttachmentFileCollector.tsx +++ b/packages/smart-forms-renderer/src/components/FormComponents/AttachmentItem/AttachmentFileCollector.tsx @@ -24,16 +24,21 @@ import type { PropsWithIsTabledAttribute } from '../../../interfaces/renderProps interface AttachmentFileCollectorProps extends PropsWithIsTabledAttribute { uploadedFile: File | null; + readOnly: boolean; onUploadFile: (file: File | null) => void; } const AttachmentFileCollector = memo(function AttachmentFileCollector( props: AttachmentFileCollectorProps ) { - const { uploadedFile, isTabled, onUploadFile } = props; + const { uploadedFile, readOnly, isTabled, onUploadFile } = props; const handleFileDrop = useCallback( (item: { files: any[] }) => { + if (readOnly) { + return; + } + if (item) { const files = item.files; @@ -61,12 +66,13 @@ const AttachmentFileCollector = memo(function AttachmentFileCollector( onDrop={handleFileDrop} file={uploadedFile} errorMessage={''} + readOnly={readOnly} isTabled={isTabled} /> - + @@ -74,7 +80,7 @@ const AttachmentFileCollector = memo(function AttachmentFileCollector( onUploadFile(null)}> diff --git a/packages/smart-forms-renderer/src/components/FormComponents/AttachmentItem/AttachmentFileDropBox.tsx b/packages/smart-forms-renderer/src/components/FormComponents/AttachmentItem/AttachmentFileDropBox.tsx index 6e5953ee1..07df1f850 100644 --- a/packages/smart-forms-renderer/src/components/FormComponents/AttachmentItem/AttachmentFileDropBox.tsx +++ b/packages/smart-forms-renderer/src/components/FormComponents/AttachmentItem/AttachmentFileDropBox.tsx @@ -26,17 +26,20 @@ export interface AttachmentFileDropBoxProps extends PropsWithIsTabledAttribute { file: File | null; onDrop: (item: { files: any[] }) => void; errorMessage: string; + readOnly: boolean; } function AttachmentFileDropBox(props: AttachmentFileDropBoxProps) { - const { file, onDrop, errorMessage, isTabled } = props; + const { file, onDrop, errorMessage, readOnly, isTabled } = props; const { canDrop, isOver, dropTarget } = useFileDrop(onDrop); const isActive = canDrop && isOver; let boxMessage = 'No file selected'; - if (isActive) { + if (readOnly) { + boxMessage = 'Item is read only'; + } else if (isActive) { boxMessage = 'Release to drop file'; } else if (errorMessage) { boxMessage = errorMessage; @@ -51,7 +54,8 @@ function AttachmentFileDropBox(props: AttachmentFileDropBoxProps) { isActive={isActive} isTabled={isTabled}> - {boxMessage} + {boxMessage} + {file ? ( Size: {getFileSize(file.size.toString() ?? '0')} diff --git a/packages/smart-forms-renderer/src/components/FormComponents/AttachmentItem/AttachmentUrlField.tsx b/packages/smart-forms-renderer/src/components/FormComponents/AttachmentItem/AttachmentUrlField.tsx index 90b9fd7ad..5d84161bd 100644 --- a/packages/smart-forms-renderer/src/components/FormComponents/AttachmentItem/AttachmentUrlField.tsx +++ b/packages/smart-forms-renderer/src/components/FormComponents/AttachmentItem/AttachmentUrlField.tsx @@ -41,7 +41,9 @@ function AttachmentUrlField(props: AttachmentUrlFieldProps) { return ( - URL + + URL + Date: Tue, 11 Jun 2024 19:35:12 +0930 Subject: [PATCH 06/10] Add playwright script to test bit of everything --- .github/workflows/main.yml | 17 -- apps/smart-forms-app/e2e/items.spec.ts | 179 ++++++++++++++++++ .../playground/components/JsonEditor.tsx | 2 + .../components/PlaygroundHeader.tsx | 3 + .../PlaygroundQuestionnairePicker.tsx | 9 +- .../GenericStatePropertyPicker.tsx | 1 + .../RendererDebugFooter/DebugResponseView.tsx | 1 + .../BooleanItem/BooleanField.tsx | 2 +- .../ChoiceItems/ChoiceAutocompleteField.tsx | 2 +- .../ChoiceRadioAnswerOptionFields.tsx | 2 +- .../ChoiceRadioAnswerValueSetFields.tsx | 2 +- .../ChoiceSelectAnswerOptionFields.tsx | 3 +- .../ChoiceSelectAnswerValueSetFields.tsx | 4 +- .../ChoiceSelectAnswerValueSetItem.tsx | 3 +- .../CustomDateItem/CustomDateField.tsx | 2 +- .../CustomDateTimeItem/CustomDateTimeItem.tsx | 2 +- .../OpenChoiceAutocompleteField.tsx | 2 +- .../OpenChoiceRadioAnswerOptionFields.tsx | 2 +- .../OpenChoiceRadioAnswerValueSetFields.tsx | 2 +- .../OpenChoiceSelectAnswerOptionField.tsx | 2 +- .../OpenChoiceSelectAnswerValueSetField.tsx | 2 +- .../FormComponents/UrlItem/UrlItem.tsx | 2 +- 22 files changed, 209 insertions(+), 37 deletions(-) create mode 100644 apps/smart-forms-app/e2e/items.spec.ts diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b9e5ba7b9..8d6063271 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -35,23 +35,6 @@ jobs: run: npm run test -w packages/smart-forms-renderer - uses: codecov/codecov-action@v4 - cypress-test: - name: Cypress Tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Run Cypress tests - uses: cypress-io/github-action@v6 - with: - browser: chrome - project: ./apps/smart-forms-app - build: npm run build -w apps/smart-forms-app - start: npm run preview -w apps/smart-forms-app - record: true - env: - CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - playwright-test: name: Playwright Tests timeout-minutes: 60 diff --git a/apps/smart-forms-app/e2e/items.spec.ts b/apps/smart-forms-app/e2e/items.spec.ts new file mode 100644 index 000000000..e913c28d2 --- /dev/null +++ b/apps/smart-forms-app/e2e/items.spec.ts @@ -0,0 +1,179 @@ +/* + * Copyright 2024 Commonwealth Scientific and Industrial Research + * Organisation (CSIRO) ABN 41 687 119 230. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { expect, test } from '@playwright/test'; +import { PLAYWRIGHT_APP_URL, PLAYWRIGHT_FORMS_SERVER_URL } from './globals'; + +const stringInput = 'Test string input'; +const textInput = 'Test text input'; +const dateInput = '25/12/2023'; +const { dtDateInput, dtTimeInput, dtPeriodInput } = { + dtDateInput: '25/12/2023', + dtTimeInput: '11:30', + dtPeriodInput: 'AM' +}; +const integerInput = '123'; +const decimalInput = '123.45'; +const urlInput = 'https://www.google.com'; +const choiceAnswerOptionInput = 'option A'; +const choiceAnswerValueSetInput = 'Tasmania'; + +test('enter inputs into BitOfEverything questionnaire', async ({ page }) => { + // Go to playground + const fetchQPromise = page.waitForResponse( + `${PLAYWRIGHT_FORMS_SERVER_URL}/Questionnaire?_count=100&_sort=-date&` + ); + const launchUrl = `${PLAYWRIGHT_APP_URL}/playground`; + await page.goto(launchUrl); + const fetchQResponse = await fetchQPromise; + expect(fetchQResponse.status()).toBe(200); + + // Select BitOfEverything questionnaire + await page + .getByTestId('questionnaire-picker-playground') + .locator('input') + .fill('bitofeverything'); + await page.keyboard.press('Enter'); + await expect(page.getByTestId('questionnaire-details-playground')).toContainText( + 'BitOfEverything' + ); + await expect(page.getByTestId('questionnaire-details-playground')).toContainText( + 'http://fhir.telstrahealth.com/fast-forms/Questionnaire/bit-of-everything' + ); + + // Build BitOfEverything questionnaire + await page.getByTestId('picker-build-form-button-playground').click(); + await expect(page.getByText('"resourceType": "Questionnaire"')).toBeInViewport(); + await expect(page.getByText('"id": "BitOfEverything"')).toBeInViewport(); + + // Enter inputs + // Display + await expect(page.getByTestId('q-item-display-box')).toContainText('display label'); + + // String + const stringItemLinkId = 'Item-string'; + await page + .getByTestId('q-item-string-box') + .getByTestId('q-item-string-field') + .locator(`#${stringItemLinkId}`) + .fill(stringInput); + + // Text + const textItemLinkId = 'Item-text'; + await page + .getByTestId('q-item-text-box') + .getByTestId('q-item-text-field') + .locator(`#${textItemLinkId}`) + .fill(textInput); + + // Boolean + const booleanItemLinkId = 'Item-bool'; + await page + .getByTestId('q-item-boolean-box') + .locator(`#${booleanItemLinkId}`) + .locator('input') + .first() + .click(); + + // Date + const dateItemLinkId = 'Item-date'; + await page + .getByTestId('q-item-date-box') + .locator(`#${dateItemLinkId}-date`) + .pressSequentially(dateInput, { delay: 100 }); + + // DateTime + const dateTimeItemLinkId = 'Item-datetime'; + await page + .getByTestId('q-item-datetime-box') + .locator(`#${dateTimeItemLinkId}-date`) + .pressSequentially(dtDateInput, { delay: 100 }); + + await page + .getByTestId('q-item-datetime-box') + .locator(`#${dateTimeItemLinkId}-time`) + .fill(dtTimeInput); + await page.getByTestId('q-item-datetime-box').locator(`#${dateTimeItemLinkId}-period`).click(); + await page.getByRole('option', { name: dtPeriodInput, exact: true }).click(); + + // Skipping Time for now + + // Integer + const integerItemLinkId = 'Item-integer'; + await page.getByTestId('q-item-integer-box').locator(`#${integerItemLinkId}`).fill(integerInput); + + // Decimal + const decimalItemLinkId = 'Item-decimal'; + await page.getByTestId('q-item-decimal-box').locator(`#${decimalItemLinkId}`).fill(decimalInput); + await expect(page.getByTestId('q-item-decimal-box').first()).toContainText('meters'); // first() is hacky + + // Url + const urlItemLinkId = 'Item-url'; + await page.getByTestId('q-item-url-box').locator(`#${urlItemLinkId}`).fill(urlInput); + + // Skipping Reference for now + + // Skipping Attachment for now + + // Skipping Quantity for now + + // Choice answerOption - option A + const choiceItemAnswerOptionLinkId = 'Item-rb-local'; + await page.getByTestId('q-item-choice-select-answer-option-box').first().scrollIntoViewIfNeeded(); + await page + .getByTestId('q-item-choice-select-answer-option-box') + .locator(`#${choiceItemAnswerOptionLinkId}`) + .pressSequentially('option a', { delay: 100 }); + await page.keyboard.press('Enter'); + + // Choice answerValueSet - Tasmania + const choiceItemAnswerValueSetLinkId = 'Item10'; + await page + .getByTestId('q-item-choice-select-answer-value-set-box') + .locator(`#${choiceItemAnswerValueSetLinkId}`) + .pressSequentially('tasmania', { delay: 100 }); + await page.keyboard.press('Enter'); + + // Check QR if our inputs are valid + await page.getByTestId('see-store-state-button-playground').click(); + await page + .getByTestId('specific-state-picker-playground') + .locator('button[value="updatableResponse"]') + .click(); + + const debugViewerText = await page.getByTestId('debug-viewer').innerText(); + expect(debugViewerText.includes(`"valueString": "${stringInput}"`)).toBeTruthy(); + expect(debugViewerText.includes(`"valueString": "${textInput}"`)).toBeTruthy(); + expect(debugViewerText.includes(`"valueBoolean": true`)).toBeTruthy(); + + expect(debugViewerText.includes(`"valueDate": "2023-12-25"`)).toBeTruthy(); + expect(debugViewerText.includes(`"valueDateTime": "2023-12-25T11:30:00+10:30"`)).toBeTruthy(); + + expect(debugViewerText.includes(`"valueInteger": ${integerInput}`)).toBeTruthy(); + expect(debugViewerText.includes(`"valueDecimal": ${decimalInput}`)).toBeTruthy(); + expect(debugViewerText.includes(`"valueUri": "${urlInput}"`)).toBeTruthy(); + + expect(debugViewerText.includes(`"system": "http://example.org/coding-test"`)).toBeTruthy(); + expect(debugViewerText.includes(`"code": "a"`)).toBeTruthy(); + expect(debugViewerText.includes(`"display": "${choiceAnswerOptionInput}"`)).toBeTruthy(); + + expect( + debugViewerText.includes(`"system": "http://fhir.telstrahealth.com/tcm/CodeSystem/ARE_local"`) + ).toBeTruthy(); + expect(debugViewerText.includes(`"code": "6"`)).toBeTruthy(); + expect(debugViewerText.includes(`"display": "${choiceAnswerValueSetInput}"`)).toBeTruthy(); +}); diff --git a/apps/smart-forms-app/src/features/playground/components/JsonEditor.tsx b/apps/smart-forms-app/src/features/playground/components/JsonEditor.tsx index 38c7a1ad5..4f6056bcc 100644 --- a/apps/smart-forms-app/src/features/playground/components/JsonEditor.tsx +++ b/apps/smart-forms-app/src/features/playground/components/JsonEditor.tsx @@ -74,6 +74,7 @@ function JsonEditor(props: Props) { {view === 'editor' ? ( + ) : ( diff --git a/apps/smart-forms-app/src/features/playground/components/StoreStateViewers/GenericStatePropertyPicker.tsx b/apps/smart-forms-app/src/features/playground/components/StoreStateViewers/GenericStatePropertyPicker.tsx index 665e18025..81f745d38 100644 --- a/apps/smart-forms-app/src/features/playground/components/StoreStateViewers/GenericStatePropertyPicker.tsx +++ b/apps/smart-forms-app/src/features/playground/components/StoreStateViewers/GenericStatePropertyPicker.tsx @@ -36,6 +36,7 @@ function GenericStatePropertyPicker(props: GenericStatePropertyPickerProps) { value={selectedProperty} sx={{ height: 28 }} exclusive + data-test="specific-state-picker-playground" onChange={(_, newSelectedProperty) => onSelectProperty(newSelectedProperty)}> {statePropertyNames.map((property) => ( onCheckedChange(e.target.value)} value={selection}> diff --git a/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceAutocompleteField.tsx b/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceAutocompleteField.tsx index 7e74b3b41..e016d1729 100644 --- a/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceAutocompleteField.tsx +++ b/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceAutocompleteField.tsx @@ -64,7 +64,7 @@ function ChoiceAutocompleteField(props: ChoiceAutocompleteFieldsProps) { return ( option.display ?? `${option.code}`} diff --git a/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceRadioAnswerOptionFields.tsx b/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceRadioAnswerOptionFields.tsx index 64fb66de9..f25b555ac 100644 --- a/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceRadioAnswerOptionFields.tsx +++ b/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceRadioAnswerOptionFields.tsx @@ -46,9 +46,9 @@ function ChoiceRadioAnswerOptionFields(props: ChoiceRadioAnswerOptionFieldsProps return ( onCheckedChange(e.target.value)} value={valueRadio} data-test="q-item-radio-group"> diff --git a/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceRadioAnswerValueSetFields.tsx b/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceRadioAnswerValueSetFields.tsx index 00374f163..f1c0a2e73 100644 --- a/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceRadioAnswerValueSetFields.tsx +++ b/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceRadioAnswerValueSetFields.tsx @@ -61,9 +61,9 @@ function ChoiceRadioAnswerValueSetFields(props: ChoiceRadioAnswerValueSetFieldsP return ( onCheckedChange(e.target.value)} value={valueRadio} data-test="q-item-radio-group"> diff --git a/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceSelectAnswerOptionFields.tsx b/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceSelectAnswerOptionFields.tsx index 01db9051a..626b2cbeb 100644 --- a/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceSelectAnswerOptionFields.tsx +++ b/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceSelectAnswerOptionFields.tsx @@ -41,7 +41,7 @@ function ChoiceSelectAnswerOptionFields(props: ChoiceSelectAnswerOptionFieldsPro return ( getAnswerOptionLabel(option)} @@ -68,7 +68,6 @@ function ChoiceSelectAnswerOptionFields(props: ChoiceSelectAnswerOptionFieldsPro ) }} - data-test="q-item-choice-dropdown-answer-value-set-field" /> )} /> diff --git a/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceSelectAnswerValueSetFields.tsx b/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceSelectAnswerValueSetFields.tsx index 136001d19..15148da79 100644 --- a/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceSelectAnswerValueSetFields.tsx +++ b/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceSelectAnswerValueSetFields.tsx @@ -54,7 +54,7 @@ function ChoiceSelectAnswerValueSetFields(props: ChoiceSelectAnswerValueSetField if (codings.length > 0) { return ( option.display ?? `${option.code}`} value={valueCoding ?? null} @@ -80,7 +80,7 @@ function ChoiceSelectAnswerValueSetFields(props: ChoiceSelectAnswerValueSetField ) }} - data-test="q-item-choice-dropdown-answer-value-set-field" + data-test="q-item-choice-select-answer-value-set-field" /> )} /> diff --git a/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceSelectAnswerValueSetItem.tsx b/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceSelectAnswerValueSetItem.tsx index 7d95ee737..5cdf38704 100644 --- a/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceSelectAnswerValueSetItem.tsx +++ b/packages/smart-forms-renderer/src/components/FormComponents/ChoiceItems/ChoiceSelectAnswerValueSetItem.tsx @@ -129,8 +129,7 @@ function ChoiceSelectAnswerValueSetItem(props: ChoiceSelectAnswerValueSetItemPro return ( onFocusLinkId(qItem.linkId)}> onFocusLinkId(qItem.linkId)}> diff --git a/packages/smart-forms-renderer/src/components/FormComponents/OpenChoiceItems/OpenChoiceAutocompleteField.tsx b/packages/smart-forms-renderer/src/components/FormComponents/OpenChoiceItems/OpenChoiceAutocompleteField.tsx index c8c37227b..512c5cd6c 100644 --- a/packages/smart-forms-renderer/src/components/FormComponents/OpenChoiceItems/OpenChoiceAutocompleteField.tsx +++ b/packages/smart-forms-renderer/src/components/FormComponents/OpenChoiceItems/OpenChoiceAutocompleteField.tsx @@ -70,7 +70,7 @@ function OpenChoiceAutocompleteField(props: OpenChoiceAutocompleteFieldProps) { return ( diff --git a/packages/smart-forms-renderer/src/components/FormComponents/OpenChoiceItems/OpenChoiceRadioAnswerOptionFields.tsx b/packages/smart-forms-renderer/src/components/FormComponents/OpenChoiceItems/OpenChoiceRadioAnswerOptionFields.tsx index 7dd1741e0..5ab76348a 100644 --- a/packages/smart-forms-renderer/src/components/FormComponents/OpenChoiceItems/OpenChoiceRadioAnswerOptionFields.tsx +++ b/packages/smart-forms-renderer/src/components/FormComponents/OpenChoiceItems/OpenChoiceRadioAnswerOptionFields.tsx @@ -51,9 +51,9 @@ function OpenChoiceRadioAnswerOptionFields(props: OpenChoiceRadioAnswerOptionFie return ( ) => onValueChange(e.target.value, null)} value={valueRadio} data-test="q-item-radio-group"> diff --git a/packages/smart-forms-renderer/src/components/FormComponents/OpenChoiceItems/OpenChoiceRadioAnswerValueSetFields.tsx b/packages/smart-forms-renderer/src/components/FormComponents/OpenChoiceItems/OpenChoiceRadioAnswerValueSetFields.tsx index 72eae98b5..9148dea5a 100644 --- a/packages/smart-forms-renderer/src/components/FormComponents/OpenChoiceItems/OpenChoiceRadioAnswerValueSetFields.tsx +++ b/packages/smart-forms-renderer/src/components/FormComponents/OpenChoiceItems/OpenChoiceRadioAnswerValueSetFields.tsx @@ -58,9 +58,9 @@ function OpenChoiceRadioAnswerValueSetFields(props: OpenChoiceRadioAnswerValueSe if (options.length > 0) { return ( ) => onValueChange(e.target.value, null)} value={valueRadio} data-test="q-item-radio-group"> diff --git a/packages/smart-forms-renderer/src/components/FormComponents/OpenChoiceItems/OpenChoiceSelectAnswerOptionField.tsx b/packages/smart-forms-renderer/src/components/FormComponents/OpenChoiceItems/OpenChoiceSelectAnswerOptionField.tsx index 5c08442db..c13232e81 100644 --- a/packages/smart-forms-renderer/src/components/FormComponents/OpenChoiceItems/OpenChoiceSelectAnswerOptionField.tsx +++ b/packages/smart-forms-renderer/src/components/FormComponents/OpenChoiceItems/OpenChoiceSelectAnswerOptionField.tsx @@ -26,7 +26,7 @@ function OpenChoiceSelectAnswerOptionField(props: OpenChoiceSelectAnswerOptionFi return ( getAnswerOptionLabel(option)} diff --git a/packages/smart-forms-renderer/src/components/FormComponents/OpenChoiceItems/OpenChoiceSelectAnswerValueSetField.tsx b/packages/smart-forms-renderer/src/components/FormComponents/OpenChoiceItems/OpenChoiceSelectAnswerValueSetField.tsx index 982772076..a1b28e7c6 100644 --- a/packages/smart-forms-renderer/src/components/FormComponents/OpenChoiceItems/OpenChoiceSelectAnswerValueSetField.tsx +++ b/packages/smart-forms-renderer/src/components/FormComponents/OpenChoiceItems/OpenChoiceSelectAnswerValueSetField.tsx @@ -30,7 +30,7 @@ function OpenChoiceSelectAnswerValueSetField(props: OpenChoiceSelectAnswerValueS return ( <> diff --git a/packages/smart-forms-renderer/src/components/FormComponents/UrlItem/UrlItem.tsx b/packages/smart-forms-renderer/src/components/FormComponents/UrlItem/UrlItem.tsx index a02c6a500..3131b567a 100644 --- a/packages/smart-forms-renderer/src/components/FormComponents/UrlItem/UrlItem.tsx +++ b/packages/smart-forms-renderer/src/components/FormComponents/UrlItem/UrlItem.tsx @@ -97,7 +97,7 @@ function UrlItem(props: UrlItemProps) { } return ( onFocusLinkId(qItem.linkId)}> From 2bebc6c707e0c9b0c7308bd3c2094533cc65f181 Mon Sep 17 00:00:00 2001 From: Sean Fong Date: Tue, 11 Jun 2024 20:45:47 +0930 Subject: [PATCH 07/10] Add playwright script to test pre-pop --- apps/smart-forms-app/e2e/prepop.spec.ts | 103 ++++++++++++++++++ .../components/PlaygroundHeader.tsx | 1 + .../components/PlaygroundPatientPicker.tsx | 1 + .../components/PlaygroundSettingsDialog.tsx | 10 +- .../PlaygroundSourceFhirServerInput.tsx | 5 +- .../components/PlaygroundUserPicker.tsx | 1 + .../components/PrePopButtonForPlayground.tsx | 7 +- 7 files changed, 124 insertions(+), 4 deletions(-) create mode 100644 apps/smart-forms-app/e2e/prepop.spec.ts diff --git a/apps/smart-forms-app/e2e/prepop.spec.ts b/apps/smart-forms-app/e2e/prepop.spec.ts new file mode 100644 index 000000000..dab0c8f07 --- /dev/null +++ b/apps/smart-forms-app/e2e/prepop.spec.ts @@ -0,0 +1,103 @@ +/* + * Copyright 2024 Commonwealth Scientific and Industrial Research + * Organisation (CSIRO) ABN 41 687 119 230. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { expect, test } from '@playwright/test'; +import { PLAYWRIGHT_APP_URL, PLAYWRIGHT_EHR_URL, PLAYWRIGHT_FORMS_SERVER_URL } from './globals'; + +test('pre-pop into CVDRiskCalculator questionnaire', async ({ page }) => { + // Go to playground + const fetchQPromise = page.waitForResponse( + `${PLAYWRIGHT_FORMS_SERVER_URL}/Questionnaire?_count=100&_sort=-date&` + ); + const launchUrl = `${PLAYWRIGHT_APP_URL}/playground`; + await page.goto(launchUrl); + const fetchQResponse = await fetchQPromise; + expect(fetchQResponse.status()).toBe(200); + + // Configure launch settings + await page.getByTestId('launch-settings-button-playground').click(); + await page.getByTestId('source-fhir-server-url-field-playground').locator('input').fill(''); + await page + .getByTestId('source-fhir-server-url-field-playground') + .locator('input') + .fill(PLAYWRIGHT_EHR_URL); + + // Validate source FHIR server url + const metadataPromise = page.waitForResponse(`${PLAYWRIGHT_EHR_URL}/metadata`); + await page.getByTestId('validate-url-button-playground').click(); + const metadataResponse = await metadataPromise; + expect(metadataResponse.status()).toBe(200); + await expect(page.getByTestId('source-fhir-server-url-field-playground')).toContainText( + 'URL validated' + ); + + // Set source FHIR server url + const patientPromise = page.waitForResponse(`${PLAYWRIGHT_EHR_URL}/Patient?_count=100`); + const practitionerPromise = page.waitForResponse(`${PLAYWRIGHT_EHR_URL}/Practitioner?_count=100`); + await page.getByTestId('set-fhir-server-button-playground').click(); + const patientResponse = await patientPromise; + expect(patientResponse.status()).toBe(200); + const practitionerResponse = await practitionerPromise; + expect(practitionerResponse.status()).toBe(200); + + // Set patient and user + await page.getByTestId('patient-picker-playground').click(); + await page.getByRole('option', { name: 'Mrs. Smart Form', exact: true }).click(); + + await page.getByTestId('user-picker-playground').click(); + await page.getByRole('option', { name: 'Dr Peter Primary', exact: true }).click(); + await page.getByTestId('save-launch-settings-button-playground').click(); + + // Select CVDRiskCalculator questionnaire + await page + .getByTestId('questionnaire-picker-playground') + .locator('input') + .fill('calculatedexpressioncvdriskcalculatorprepop'); + await page.keyboard.press('Enter'); + await expect(page.getByTestId('questionnaire-details-playground')).toContainText( + 'CalculatedExpressionCvdRiskCalculatorPrepop' + ); + await expect(page.getByTestId('questionnaire-details-playground')).toContainText( + 'https://smartforms.csiro.au/docs/sdc/population/calculated-expression-2' + ); + + // Build CVDRiskCalculator questionnaire + await page.getByTestId('picker-build-form-button-playground').click(); + await expect(page.getByText('"resourceType": "Questionnaire"')).toBeInViewport(); + await expect( + page.getByText('"id": "CalculatedExpressionCvdRiskCalculatorPrepop"') + ).toBeInViewport(); + + // Ensure questionnaire is built + await expect(page.getByTestId('q-item-display-box')).toContainText( + 'The calculator below should only be used for technology demonstration purposes.' + ); + + // Perform pre-population + const populatePromise = page.waitForResponse( + new RegExp(/^https:\/\/proxy\.smartforms\.io\/v\/r4\/fhir\/(Observation|Condition)\?.+$/) + ); + await page.getByTestId('prepop-button-playground').click(); + const populateResponse = await populatePromise; + expect(populateResponse.status()).toBe(200); + + // Check calculated value + const cvdRiskValueLinkId = 'cvd-result'; + await expect( + page.getByTestId('q-item-integer-box').locator(`#${cvdRiskValueLinkId}`) + ).toHaveValue('23'); +}); diff --git a/apps/smart-forms-app/src/features/playground/components/PlaygroundHeader.tsx b/apps/smart-forms-app/src/features/playground/components/PlaygroundHeader.tsx index e3b45a634..3cf8333c9 100644 --- a/apps/smart-forms-app/src/features/playground/components/PlaygroundHeader.tsx +++ b/apps/smart-forms-app/src/features/playground/components/PlaygroundHeader.tsx @@ -85,6 +85,7 @@ const PlaygroundHeader = memo(function PlaygroundHeader(props: PlaygroundHeaderP { setSettingsDialogOpen(true); }}> diff --git a/apps/smart-forms-app/src/features/playground/components/PlaygroundPatientPicker.tsx b/apps/smart-forms-app/src/features/playground/components/PlaygroundPatientPicker.tsx index bdb0a4dd3..cb3b0e42d 100644 --- a/apps/smart-forms-app/src/features/playground/components/PlaygroundPatientPicker.tsx +++ b/apps/smart-forms-app/src/features/playground/components/PlaygroundPatientPicker.tsx @@ -84,6 +84,7 @@ function PlaygroundPatientPicker(props: PlaygroundPatientPickerProps) { value={selectedPatientId ?? ''} size="small" fullWidth={true} + data-test="patient-picker-playground" onChange={(e) => handleSelectPatient(e.target.value)}> {patients.map((patient) => ( diff --git a/apps/smart-forms-app/src/features/playground/components/PlaygroundSettingsDialog.tsx b/apps/smart-forms-app/src/features/playground/components/PlaygroundSettingsDialog.tsx index a26cefb70..b81f789d4 100644 --- a/apps/smart-forms-app/src/features/playground/components/PlaygroundSettingsDialog.tsx +++ b/apps/smart-forms-app/src/features/playground/components/PlaygroundSettingsDialog.tsx @@ -101,7 +101,10 @@ function PlaygroundSettingsDialog(props: Props) { onValidateFhirServerUrlInput={handleValidateFhirServerUrl} /> - @@ -121,7 +124,10 @@ function PlaygroundSettingsDialog(props: Props) { - diff --git a/apps/smart-forms-app/src/features/playground/components/PlaygroundSourceFhirServerInput.tsx b/apps/smart-forms-app/src/features/playground/components/PlaygroundSourceFhirServerInput.tsx index 92b859b5a..4e7dce0de 100644 --- a/apps/smart-forms-app/src/features/playground/components/PlaygroundSourceFhirServerInput.tsx +++ b/apps/smart-forms-app/src/features/playground/components/PlaygroundSourceFhirServerInput.tsx @@ -75,6 +75,7 @@ function PlaygroundSourceFhirServerInput(props: PlaygroundSourceFhirServerInputP helperText={feedbackMessage ?? ''} fullWidth sx={{ minWidth: 350 }} + data-test="source-fhir-server-url-field-playground" InputProps={{ endAdornment: ( @@ -88,7 +89,9 @@ function PlaygroundSourceFhirServerInput(props: PlaygroundSourceFhirServerInputP {fhirServerUrlInputValid === 'unchecked' ? ( - + diff --git a/apps/smart-forms-app/src/features/playground/components/PlaygroundUserPicker.tsx b/apps/smart-forms-app/src/features/playground/components/PlaygroundUserPicker.tsx index 049fbcef4..4a5de89fd 100644 --- a/apps/smart-forms-app/src/features/playground/components/PlaygroundUserPicker.tsx +++ b/apps/smart-forms-app/src/features/playground/components/PlaygroundUserPicker.tsx @@ -86,6 +86,7 @@ function PlaygroundUserPicker(props: PlaygroundPractitionerPickerProps) { value={selectedUserId ?? ''} size="small" fullWidth={true} + data-test="user-picker-playground" onChange={(e) => handleSelectUser(e.target.value)}> {practitioners.map((patient) => ( diff --git a/apps/smart-forms-app/src/features/playground/components/PrePopButtonForPlayground.tsx b/apps/smart-forms-app/src/features/playground/components/PrePopButtonForPlayground.tsx index 96b994c9c..848e5e889 100644 --- a/apps/smart-forms-app/src/features/playground/components/PrePopButtonForPlayground.tsx +++ b/apps/smart-forms-app/src/features/playground/components/PrePopButtonForPlayground.tsx @@ -33,7 +33,12 @@ function PrePopButtonForPlayground(props: PrePopButtonForPlaygroundProps) { <> - + {isPopulating ? ( ) : ( From 17b6a7635996bcf3f56774489ad177c2f34550b8 Mon Sep 17 00:00:00 2001 From: Sean Fong Date: Tue, 11 Jun 2024 20:49:39 +0930 Subject: [PATCH 08/10] Update package versions --- apps/smart-forms-app/package.json | 2 +- package-lock.json | 4 ++-- packages/smart-forms-renderer/package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/smart-forms-app/package.json b/apps/smart-forms-app/package.json index 9aec525a6..367097c65 100644 --- a/apps/smart-forms-app/package.json +++ b/apps/smart-forms-app/package.json @@ -29,7 +29,7 @@ "dependencies": { "@aehrc/sdc-assemble": "^1.2.0", "@aehrc/sdc-populate": "^2.2.1", - "@aehrc/smart-forms-renderer": "^0.35.1", + "@aehrc/smart-forms-renderer": "^0.35.2", "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.5", "@fontsource/material-icons": "^5.0.16", diff --git a/package-lock.json b/package-lock.json index ccf9390d5..77411e85a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -51,7 +51,7 @@ "dependencies": { "@aehrc/sdc-assemble": "^1.2.0", "@aehrc/sdc-populate": "^2.2.1", - "@aehrc/smart-forms-renderer": "^0.35.1", + "@aehrc/smart-forms-renderer": "^0.35.2", "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.5", "@fontsource/material-icons": "^5.0.16", @@ -44132,7 +44132,7 @@ }, "packages/smart-forms-renderer": { "name": "@aehrc/smart-forms-renderer", - "version": "0.35.1", + "version": "0.35.2", "license": "Apache-2.0", "dependencies": { "@aehrc/sdc-populate": "^2.2.1", diff --git a/packages/smart-forms-renderer/package.json b/packages/smart-forms-renderer/package.json index 600a4a744..6a1e4d43e 100644 --- a/packages/smart-forms-renderer/package.json +++ b/packages/smart-forms-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@aehrc/smart-forms-renderer", - "version": "0.35.1", + "version": "0.35.2", "description": "FHIR Structured Data Captured (SDC) rendering engine for Smart Forms", "main": "lib/index.js", "scripts": { From 25ca83f34101329025bd9867b272e9fefee5905f Mon Sep 17 00:00:00 2001 From: Sean Fong Date: Tue, 11 Jun 2024 20:53:20 +0930 Subject: [PATCH 09/10] Fix datetime timezone issue --- apps/smart-forms-app/e2e/items.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/smart-forms-app/e2e/items.spec.ts b/apps/smart-forms-app/e2e/items.spec.ts index e913c28d2..1f27506af 100644 --- a/apps/smart-forms-app/e2e/items.spec.ts +++ b/apps/smart-forms-app/e2e/items.spec.ts @@ -161,7 +161,7 @@ test('enter inputs into BitOfEverything questionnaire', async ({ page }) => { expect(debugViewerText.includes(`"valueBoolean": true`)).toBeTruthy(); expect(debugViewerText.includes(`"valueDate": "2023-12-25"`)).toBeTruthy(); - expect(debugViewerText.includes(`"valueDateTime": "2023-12-25T11:30:00+10:30"`)).toBeTruthy(); + expect(debugViewerText.includes(`"valueDateTime": "2023-12-25T11:30:00"`)).toBeTruthy(); expect(debugViewerText.includes(`"valueInteger": ${integerInput}`)).toBeTruthy(); expect(debugViewerText.includes(`"valueDecimal": ${decimalInput}`)).toBeTruthy(); From 8a7147fcbc58f0d3f66a803a8fc09916bb7d90e5 Mon Sep 17 00:00:00 2001 From: Sean Fong Date: Tue, 11 Jun 2024 21:03:43 +0930 Subject: [PATCH 10/10] Fix datetime timezone issue #2 --- apps/smart-forms-app/e2e/items.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/smart-forms-app/e2e/items.spec.ts b/apps/smart-forms-app/e2e/items.spec.ts index 1f27506af..c65044b54 100644 --- a/apps/smart-forms-app/e2e/items.spec.ts +++ b/apps/smart-forms-app/e2e/items.spec.ts @@ -161,7 +161,7 @@ test('enter inputs into BitOfEverything questionnaire', async ({ page }) => { expect(debugViewerText.includes(`"valueBoolean": true`)).toBeTruthy(); expect(debugViewerText.includes(`"valueDate": "2023-12-25"`)).toBeTruthy(); - expect(debugViewerText.includes(`"valueDateTime": "2023-12-25T11:30:00"`)).toBeTruthy(); + expect(debugViewerText.includes(`"valueDateTime": "2023-12-25T11:30:00`)).toBeTruthy(); expect(debugViewerText.includes(`"valueInteger": ${integerInput}`)).toBeTruthy(); expect(debugViewerText.includes(`"valueDecimal": ${decimalInput}`)).toBeTruthy();