Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

working tests. #46

Merged
merged 11 commits into from
Jun 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,7 @@

js/dist
js/node_modules

js/local.log
js/playwright-report
js/test-results
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,10 @@ ones that Fasten supports
| [clients/internal/source](./clients/internal/source) | Automatically created OAuth clients for accessing production data from various healthcare institutions. Usually inherit from Platform clients |
| [definitions](./definitions/) | Automatically created definition files. These files are generated from files created by `fasten-sources-gen` and are used by Fasten Lighthouse. |



# References

## NPM Library
- https://www.tsmean.com/articles/learn-typescript/typescript-module-compiler-option/
-
52 changes: 52 additions & 0 deletions js/e2e/browserstack.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import * as cp from 'child_process';
const clientPlaywrightVersion = cp
.execSync('npx playwright --version')
.toString()
.trim()
.split(' ')[1];
import * as BrowserStackLocal from'browserstack-local';
import * as util from'util';
import process from 'process';

// BrowserStack Specific Capabilities.
// Set 'browserstack.local:true For Local testing
const caps = {
browser: 'chrome',
os: 'osx',
os_version: 'catalina',
name: 'My first playwright test',
build: 'playwright-build',
'browserstack.username': process.env.BROWSERSTACK_USERNAME || 'USERNAME',
'browserstack.accessKey': process.env.BROWSERSTACK_ACCESS_KEY || 'ACCESSKEY',
'browserstack.local': process.env.BROWSERSTACK_LOCAL || true,
'client.playwrightVersion': clientPlaywrightVersion,
};

export const bsLocal = new BrowserStackLocal.Local();

// replace YOUR_ACCESS_KEY with your key. You can also set an environment variable - "BROWSERSTACK_ACCESS_KEY".
export const BS_LOCAL_ARGS = {
key: process.env.BROWSERSTACK_ACCESS_KEY || 'ACCESSKEY',
};

// Patching the capabilities dynamically according to the project name.
const patchCaps = (name, title) => {
let combination = name.split(/@browserstack/)[0];
let [browerCaps, osCaps] = combination.split(/:/);
let [browser, browser_version] = browerCaps.split(/@/);
let osCapsSplit = osCaps.split(/ /);
let os = osCapsSplit.shift();
let os_version = osCapsSplit.join(' ');
caps.browser = browser ? browser : 'chrome';
caps.os_version = browser_version ? browser_version : 'latest';
caps.os = os ? os : 'osx';
caps.os_version = os_version ? os_version : 'catalina';
caps.name = title;
};

export function getCdpEndpoint(name, title){
patchCaps(name, title)
const cdpUrl = `wss:https://cdp.browserstack.com/playwright?caps=${encodeURIComponent(JSON.stringify(caps))}`
console.log(`--> ${cdpUrl}`)
return cdpUrl;
}
25 changes: 25 additions & 0 deletions js/e2e/global-setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// global-setup.js
import { bsLocal, BS_LOCAL_ARGS } from './browserstack.config';
import { promisify } from 'util';
const sleep = promisify(setTimeout);
const redColour = '\x1b[31m';
const whiteColour = '\x1b[0m';

export default async function setup() {
console.log('Starting BrowserStackLocal ...');
// Starts the Local instance with the required arguments
let localResponseReceived = false;
bsLocal.start(BS_LOCAL_ARGS, (err) => {
if (err) {
console.error(
`${redColour}Error starting BrowserStackLocal${whiteColour}`, err
);
} else {
console.log('BrowserStackLocal Started');
}
localResponseReceived = true;
});
while (!localResponseReceived) {
await sleep(1000);
}
};
18 changes: 18 additions & 0 deletions js/e2e/global-teardown.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// global-teardown.js
import { bsLocal } from './browserstack.config';
import { promisify } from'util';
const sleep = promisify(setTimeout);
export default async function teardown(){
// Stop the Local instance after your test run is completed, i.e after driver.quit
let localStopped = false;

if (bsLocal && bsLocal.isRunning()) {
bsLocal.stop(() => {
localStopped = true;
console.log('Stopped BrowserStackLocal');
});
while (!localStopped) {
await sleep(1000);
}
}
}
32 changes: 32 additions & 0 deletions js/e2e/protractor.conf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// @ts-check
// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts

const { SpecReporter } = require('jasmine-spec-reporter');

/**
* @type { import("protractor").Config }
*/
exports.config = {
allScriptsTimeout: 11000,
specs: [
'./src/**/*.e2e-spec.ts'
],
capabilities: {
browserName: 'chrome'
},
directConnect: true,
baseUrl: 'http:https://localhost:4200/',
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000,
print: function() {}
},
onPrepare() {
require('ts-node').register({
project: require('path').join(__dirname, './tsconfig.json')
});
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
}
};
37 changes: 37 additions & 0 deletions js/e2e/src/aetna_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { test, expect } from "@playwright/test";
import {getEndpointDefinition} from '../utils';
import {generateSourceAuthorizeUrl} from '../../src/connect/authorization-url';

test("Aetna Login Flow", async ({page}, testInfo) => {
try {
await page.evaluate(_ => {},`browserstack_executor: ${JSON.stringify({action: "setSessionName", arguments: {name:testInfo.title}})}`);
await page.waitForTimeout(5000);

//get the Cerner Sandbox endpoint definition
let endpointDefinition = await getEndpointDefinition('ac8308d1-90de-4994-bb3d-fe404832714c')
let authorizeData = await generateSourceAuthorizeUrl(endpointDefinition)

// authorizeData.sourceState
console.log(authorizeData.url.toString())

// Start login flow by clicking on button with text "Login to MyChart"
await page.goto(authorizeData.url.toString());

// We are on login page
await page.waitForSelector("text=Welcome to Aetna");
// await expect(page).toHaveTitle("Cerner Health - Sign In");
await page.click("label[for='username']", { force: true });
await page.keyboard.type("aetnaTestUser3 ");
await page.click("label[for='password']", { force: true });
await page.keyboard.type("FHIRdemo2020");
await page.click("#loginButton");

// If successful, Fasten Lighthouse page should now be visible
await page.waitForSelector("text=Your account has been securely connected to FASTEN.");

await page.evaluate(_ => {}, `browserstack_executor: ${JSON.stringify({action: 'setSessionStatus',arguments: {status: 'passed',reason: 'Authentication Successful'}})}`);
} catch (e) {
console.log(e);
await page.evaluate(_ => {}, `browserstack_executor: ${JSON.stringify({action: 'setSessionStatus',arguments: {status: 'failed',reason: 'Test failed'}})}`);
}
});
41 changes: 41 additions & 0 deletions js/e2e/src/allscripts_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { test, expect } from "@playwright/test";
import {getEndpointDefinition} from '../utils';
import {generateSourceAuthorizeUrl} from '../../src/connect/authorization-url';

test("Allscripts Login Flow", async ({page}, testInfo) => {
try{
await page.evaluate(_ => {},`browserstack_executor: ${JSON.stringify({action: "setSessionName", arguments: {name:testInfo.title}})}`);
await page.waitForTimeout(5000);

//get the Allscripts - Veradigm Sandbox endpoint definition
let endpointDefinition = await getEndpointDefinition('7682675b-8247-4fda-b2cd-048bfeafc8af')
let authorizeData = await generateSourceAuthorizeUrl(endpointDefinition)

// authorizeData.sourceState
console.log(authorizeData.url.toString())

await page.goto(authorizeData.url.toString());

// We are on login page
await page.waitForSelector("text=Allscripts Health Connect Core");
await expect(page).toHaveTitle("Allscripts FHIR Authorization - ");
await page.focus("#username");
await page.keyboard.type("[email protected]");
await page.focus("#passwordEntered");
await page.keyboard.type("Allscripts#1");
await page.click("#local-login");

// We have logged in
await page.waitForSelector("text=Uncheck the permissions you do not wish to grant.");
await expect(page).toHaveTitle("Allscripts FHIR Authorization - ");
await page.click('button[value="yes"]');

// If successful, Fasten Lighthouse page should now be visible
await page.waitForSelector("text=Your account has been securely connected to FASTEN.");

await page.evaluate(_ => {}, `browserstack_executor: ${JSON.stringify({action: 'setSessionStatus',arguments: {status: 'passed',reason: 'Authentication Successful'}})}`);
} catch (e) {
console.log(e);
await page.evaluate(_ => {}, `browserstack_executor: ${JSON.stringify({action: 'setSessionStatus',arguments: {status: 'failed',reason: 'Test failed'}})}`);
}
});
41 changes: 41 additions & 0 deletions js/e2e/src/athena_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { test, expect } from "@playwright/test";
import {getEndpointDefinition} from '../utils';
import {generateSourceAuthorizeUrl} from '../../src/connect/authorization-url';

test("Athena Login Flow", async ({page}, testInfo) => {
try {
await page.evaluate(_ => {},`browserstack_executor: ${JSON.stringify({action: "setSessionName", arguments: {name:testInfo.title}})}`);
await page.waitForTimeout(5000);
//get the Cerner Sandbox endpoint definition
let endpointDefinition = await getEndpointDefinition('950e9092-8ce7-4926-ad87-64616f00cb4c')
let authorizeData = await generateSourceAuthorizeUrl(endpointDefinition)

// authorizeData.sourceState
console.log(authorizeData.url.toString())

// Start login flow by clicking on button with text "Login to MyChart"
await page.goto(authorizeData.url.toString());

// We are on login page
await page.waitForSelector("text=Fasten Health - preview");
await expect(page).toHaveTitle("Login");
await page.click("label[for='okta-signin-username']", { force: true });
await page.keyboard.type("[email protected]");
await page.click("label[for='okta-signin-password']", { force: true });
await page.keyboard.type("Password1");
await page.click("#okta-signin-submit");

// We have logged in
await page.waitForSelector("text=Select a health record");
await expect(page).toHaveTitle("Login");
await page.locator("text=Jake Medlock (you)").click();

// If successful, Fasten Lighthouse page should now be visible
await page.waitForSelector("text=Your account has been securely connected to FASTEN.");

await page.evaluate(_ => {}, `browserstack_executor: ${JSON.stringify({action: 'setSessionStatus',arguments: {status: 'passed',reason: 'Authentication Successful'}})}`);
} catch (e) {
console.log(e);
await page.evaluate(_ => {}, `browserstack_executor: ${JSON.stringify({action: 'setSessionStatus',arguments: {status: 'failed',reason: 'Test failed'}})}`);
}
});
41 changes: 41 additions & 0 deletions js/e2e/src/careevolution_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { test, expect } from "@playwright/test";
import {getEndpointDefinition} from '../utils';
import {generateSourceAuthorizeUrl} from '../../src/connect/authorization-url';

test("CareEvolution Login Flow", async ({page}, testInfo) => {
try {
await page.evaluate(_ => {},`browserstack_executor: ${JSON.stringify({action: "setSessionName", arguments: {name:testInfo.title}})}`);
await page.waitForTimeout(5000);

//get the CareEvolution Sandbox endpoint definition
let endpointDefinition = await getEndpointDefinition('8b47cf7b-330e-4ede-9967-4caa7be623aa')
let authorizeData = await generateSourceAuthorizeUrl(endpointDefinition)

// authorizeData.sourceState
console.log(authorizeData.url.toString())

// Start login flow by clicking on button with text "Login to MyChart"
await page.goto(authorizeData.url.toString());

// We are on login page
await page.waitForSelector("#login-button");
await page.focus("#Username");
await page.keyboard.type("CEPatient");
await page.focus("#Password");
await page.keyboard.type("CEPatient2018");
await page.click("#login-button");

// We have logged in
await page.waitForSelector("text=Whose record do you want to allow access to?");
// await expect(page).toHaveText("Authorization Request");
await page.locator("text=Fran Demoski (28)").click();
await page.click('input[value="Agree"]');

// If successful, Fasten Lighthouse page should now be visible
await page.waitForSelector("text=Your account has been securely connected to FASTEN.");
await page.evaluate(_ => {}, `browserstack_executor: ${JSON.stringify({action: 'setSessionStatus',arguments: {status: 'passed',reason: 'Authentication Successful'}})}`);
} catch (e) {
console.log(e);
await page.evaluate(_ => {}, `browserstack_executor: ${JSON.stringify({action: 'setSessionStatus',arguments: {status: 'failed',reason: 'Test failed'}})}`);
}
});
49 changes: 49 additions & 0 deletions js/e2e/src/cerner_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { test, expect } from "@playwright/test";
import {getEndpointDefinition} from '../utils';
import {generateSourceAuthorizeUrl} from '../../src/connect/authorization-url';

test("Cerner Login Flow", async ({page}, testInfo) => {
try {
await page.evaluate(_ => {},`browserstack_executor: ${JSON.stringify({action: "setSessionName", arguments: {name:testInfo.title}})}`);
await page.waitForTimeout(5000);

//get the Cerner Sandbox endpoint definition
let endpointDefinition = await getEndpointDefinition('3290e5d7-978e-42ad-b661-1cf8a01a989c')
let authorizeData = await generateSourceAuthorizeUrl(endpointDefinition)

// authorizeData.sourceState
console.log(authorizeData.url.toString())

// Start login flow by clicking on button with text "Login to MyChart"
await page.goto(authorizeData.url.toString());

// We are on login page
await page.waitForSelector("text=FhirPlay Non-Prod");
await expect(page).toHaveTitle("Cerner Health - Sign In");
await page.click("label[for='id_login_username']", { force: true });
await page.keyboard.type("nancysmart");
await page.click("label[for='id_login_password']", { force: true });
await page.keyboard.type("Cerner01");
await page.click("#signin");

// We have logged in
await page.waitForSelector("text=Warning: Unknown app");
await expect(page).toHaveTitle("Authorization Needed");
await page.click('#proceedButton');

// We are on the Select Patient page.
await page.waitForSelector("text=SMART II, NANCY (Self, 33)");
await expect(page).toHaveTitle("Authorization Needed");
await page.click("label[for='12724066']", { force: true, delay: 500 });
await page.click("#allowButton");


// If successful, Fasten Lighthouse page should now be visible
await page.waitForSelector("text=Your account has been securely connected to FASTEN.");

await page.evaluate(_ => {}, `browserstack_executor: ${JSON.stringify({action: 'setSessionStatus',arguments: {status: 'passed',reason: 'Authentication Successful'}})}`);
} catch (e) {
console.log(e);
await page.evaluate(_ => {}, `browserstack_executor: ${JSON.stringify({action: 'setSessionStatus',arguments: {status: 'failed',reason: 'Test failed'}})}`);
}
});
Loading
Loading