Skip to content

Commit

Permalink
Merge pull request #846 from aehrc/feature/playwright
Browse files Browse the repository at this point in the history
Feature/playwright
  • Loading branch information
fongsean authored Jun 11, 2024
2 parents 348b070 + 8a7147f commit b566536
Show file tree
Hide file tree
Showing 45 changed files with 1,040 additions and 67 deletions.
28 changes: 18 additions & 10 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,30 @@ jobs:
run: npm run test -w packages/smart-forms-renderer
- uses: codecov/codecov-action@v4

cypress-test:
name: Cypress Tests
playwright-test:
name: Playwright Tests
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Cypress tests
uses: cypress-io/github-action@v6
- 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: npm run playwright -w apps/smart-forms-app
- uses: actions/upload-artifact@v4
if: always()
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 }}
name: playwright-report
path: playwright-report/
retention-days: 30

lint:
name: Lint
Expand Down
6 changes: 5 additions & 1 deletion apps/smart-forms-app/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,8 @@ yarn-error.log*
# cypress non-test files
cypress/screenshots
cypress/videos
temp
temp
/test-results/
/playwright-report/
/blob-report/
/playwright/.cache/
70 changes: 70 additions & 0 deletions apps/smart-forms-app/e2e/_pre-run.spec.ts
Original file line number Diff line number Diff line change
@@ -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();
});
56 changes: 56 additions & 0 deletions apps/smart-forms-app/e2e/dashboard.spec.ts
Original file line number Diff line number Diff line change
@@ -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);
});
21 changes: 21 additions & 0 deletions apps/smart-forms-app/e2e/globals.ts
Original file line number Diff line number Diff line change
@@ -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';
179 changes: 179 additions & 0 deletions apps/smart-forms-app/e2e/items.spec.ts
Original file line number Diff line number Diff line change
@@ -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`)).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();
});
Loading

0 comments on commit b566536

Please sign in to comment.