Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
a28c308
FO-51 First automation test - Dashboard & Source page
beatrix-tsa Jul 28, 2025
6ce19cc
FO-51 Add Medical History – Condition Medical Record Wizard
beatrix-tsa Jul 29, 2025
92210ab
FO-51: Automated Medical Record Addition in Medical History and PDF E…
beatrix-tsa Jul 30, 2025
57181e3
FO-51 Export PDF and verify history record
beatrix-tsa Jul 31, 2025
65dde9a
Merge branch 'main' into FO-51
alexszilagyi Aug 11, 2025
144694e
E2E tests: updated test cases
alexszilagyi Aug 13, 2025
2519f8f
FO-52 [TEST CASE] Medical Dashboard Load and Data Display
alexszilagyi Aug 22, 2025
56c6b07
FO-52 [TEST CASE] Medical Dashboard Load and Data Display
alexszilagyi Aug 25, 2025
f87f0f0
Created user tests and added dashboard verification
alexszilagyi Aug 26, 2025
c00404f
FO-56 [TEST CASE] Verify Lab Observations Display and Details
alexszilagyi Aug 27, 2025
59ec25b
FO-56 [TEST CASE] Verify Lab Observations Display and Details
alexszilagyi Aug 28, 2025
6dda75f
FO-56 [TEST CASE] Verify Lab Observations Display and Details
alexszilagyi Aug 29, 2025
a9b98ca
Merge remote-tracking branch 'origin/main' into FO-51
alexszilagyi Sep 8, 2025
f4a4d59
Merge branch 'main' into FO-51
alexszilagyi Sep 8, 2025
11a3b30
fix: revert assets sourcers
alexszilagyi Sep 8, 2025
8b06717
Fixed code and added asserts
alexszilagyi Sep 9, 2025
11e4220
WIP: salvare temporară
alexszilagyi Sep 10, 2025
151a0fa
fix: taking out hardcoded values and using dynamic checks
alexszilagyi Sep 11, 2025
fed945c
FO-80: [TEST CASE] Verify Address Book
alexszilagyi Sep 11, 2025
57ff55f
Completed AddressBook page object with all input methods
alexszilagyi Sep 12, 2025
ff0c896
fix: delete for windows changes
alexszilagyi Sep 15, 2025
2cc1aa2
Merge remote-tracking branch 'origin/FO-80-verify-address-book' into …
alexszilagyi Sep 15, 2025
8fde19d
renamed file and added authentication flow for new users
alexszilagyi Sep 15, 2025
b4ba39b
WIP: Refactoring code and adding assert
alexszilagyi Sep 16, 2025
0f49b2d
Merge branch 'main' of https://github.com/TechStackApps/fasten-onprem…
alexszilagyi Sep 17, 2025
7885581
fix: refactor function names
alexszilagyi Sep 17, 2025
80bf5fc
add Settings page
alexszilagyi Sep 18, 2025
da5e18e
fix: small change
alexszilagyi Sep 19, 2025
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
54 changes: 41 additions & 13 deletions frontend/e2e/protractor.conf.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,60 @@
// @ts-check
// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts
const path = require('path');

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

/**
* @type { import("protractor").Config }
*/
exports.config = {
allScriptsTimeout: 11000,


specs: [
'./src/**/*.e2e-spec.ts'
//'./src/**/*.e2e-spec.ts',
'./src/login.e2e-spec.ts',
'./src/dashboard.e2e-spec.ts',
'./src/sources.e2e-spec.ts',
'./src/backGroundJobHistory.e2e-spec.ts',
'./src/medicalHistory.e2e-spec.ts',
'./src/users.e2e-spec.ts',
'./src/labs.e2e-spec.ts'
],

capabilities: {
browserName: 'chrome'
browserName: 'chrome',
args: ['--headless=new', '--disable-notifications', '--disable-dev-shm-usage'],

chromeOptions: {
args: [
//'--headless',
'--disable-infobars',
'--no-sandbox',
'--disable-dev-shm-usage',
'--disable-gpu',
'--disable-software-rasterizer',
'--log-level=3'
],
excludeSwitches: ['enable-logging'],

prefs: {
'download.default_directory': path.resolve(__dirname, 'downloads'),
'download.prompt_for_download': false,
'download.directory_upgrade': true,
'plugins.always_open_pdf_externally': true
}
}
},

chromeDriver: '../chromedriver-win64/chromedriver.exe',

directConnect: true,
baseUrl: 'http://localhost:4200/',
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000,
print: function() {}
print: function () { }
},
onPrepare() {
require('ts-node').register({
project: require('path').join(__dirname, './tsconfig.json')
});
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
const { SpecReporter } = require('jasmine-spec-reporter');
jasmine.getEnv().addReporter(new SpecReporter());
}
};
};
108 changes: 108 additions & 0 deletions frontend/e2e/src/address-book.e2e-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import { browser } from 'protractor';
import { loginAsUser } from './helpers/auth.helper';
import { AddressBookPage } from './pages/address-book.po';
import * as fs from 'fs';
import * as path from 'path';

describe('Navigate to Address Book page and add new practitioner', () => {
let addressBook: AddressBookPage;
const existingPractitioner = 'JOHNSON, MICHAEL';
const newPractitioner = 'NEW TEST PRACTITIONER DENTIST';

beforeAll(async () => {
addressBook = new AddressBookPage();
await browser.waitForAngularEnabled(true);
await browser.driver.manage().window().maximize();
await loginAsUser('user', '[email protected]');
});

it('should navigate to Address Book page', async () => {
await addressBook.clickAddressBook();
const currentUrl = await browser.getCurrentUrl();
expect(currentUrl).toContain('/practitioners');
const titleText = await addressBook.getPageTitle();
expect(titleText).toContain('Address book');
});

it('should open Add New Practitioner page', async () => {
await addressBook.clickNewPractitioner();
const addTitle = await addressBook.getAddPractitionerTitle();
expect(addTitle).toBe('Add New Practitioner');
});

it('should create new practitioner', async () => {
await addressBook.typeName(existingPractitioner);
await addressBook.clickCreatePractitioner();
await addressBook.handleSuccessAlert('Practitioner created successfully!');
const found = await addressBook.isPractitionerInList(existingPractitioner);
expect(found).toBe(true);
});

it('should open practitioner details', async () => {
await addressBook.typePractitionerName(existingPractitioner);
await addressBook.clickOnPractitioner(existingPractitioner);
expect(await addressBook.isContactDetailsSectionVisible()).toBe(true);
});

it('should show practitioner contact details', async () => {
const contactDetails = await addressBook.getContactDetailsElements();
expect(await contactDetails.phone.isPresent()).toBe(true);
expect(await contactDetails.address.isPresent()).toBe(true);
expect(await contactDetails.resourceId.isPresent()).toBe(true);
});

it('should show history section', async () => {
const historySection = await addressBook.getHistorySection();
expect(await historySection.isPresent()).toBe(true);
await addressBook.clickBack();
const titleText = await addressBook.getPageTitle();
expect(titleText).toContain('Address book');
});

it('should delete practitioner from Address Book', async () => {
const { confirmText, successText } = await addressBook.deletePractitioner(existingPractitioner);
expect(confirmText).toContain(`Are you sure you want to delete ${existingPractitioner}`);
expect(successText).toBe(`Successfully deleted ${existingPractitioner}.`);
const found = await addressBook.isPractitionerInList(existingPractitioner);
expect(found).toBe(false);
});

it('adding a new practitioner to the Address book', async () => {
await addressBook.clickNewPractitioner();
await addressBook.typeName(newPractitioner);
await addressBook.typeProfession('Dentist');
await addressBook.typePhone('0712345678');
await addressBook.typeFax('0212345678');
await addressBook.typeEmail('[email protected]');
await addressBook.typeAddressDetails('Apartment 12, 3rd Floor, Building A');
await addressBook.typeCity('New York');
await addressBook.typeStateOrProvince('California');
await addressBook.typeZipOrPostalCode('10001');
await addressBook.typeCountry('United States');
await addressBook.clickCreatePractitioner();
await addressBook.handleSuccessAlert('Practitioner created successfully!');
const found = await addressBook.isPractitionerInList(newPractitioner);
expect(found).toBe(true);
});

it('Verify practitioner export file exists', async () => {
const downloadsDir = path.resolve(__dirname, '../downloads');
if (!fs.existsSync(downloadsDir)) {
fs.mkdirSync(downloadsDir);
}
await addressBook.exportPractitionerAsCSV(newPractitioner);
await browser.sleep(5000);
const latestCSV = await addressBook.getLatestExportedCSV(downloadsDir);
expect(latestCSV).not.toBeNull();
expect(path.basename(latestCSV!)).toMatch(/^practitioners-export-.*\.csv$/);
expect(fs.existsSync(latestCSV!)).toBe(true);
});

it('Delete added new practitioner', async () => {
const { confirmText, successText } = await addressBook.deletePractitioner(newPractitioner);
expect(confirmText).toContain(`Are you sure you want to delete ${newPractitioner}?`);
expect(successText).toBe(`Successfully deleted ${newPractitioner}.`);
const found = await addressBook.isPractitionerInList(newPractitioner);
expect(found).toBe(false);
});
});
32 changes: 32 additions & 0 deletions frontend/e2e/src/authentication.e2e-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { browser } from 'protractor';
import { AuthenticationPage } from './pages/authentication.po';

describe('Create and Authenticate New User', () => {

let authenticationPage: AuthenticationPage;

beforeAll(async () => {
authenticationPage = new AuthenticationPage();
await browser.driver.manage().window().maximize();
await browser.waitForAngularEnabled(true);
});

it('should create a new user in the app', async () => {
await browser.get('/auth/signup/wizard');

const currentUrl = await browser.getCurrentUrl();
expect(currentUrl).toContain('/auth/signup/wizard');

const title = authenticationPage.getStartTitle();
expect(await title.getText()).toEqual("Let's Get Started!");

await authenticationPage.enterFullName('John Doe');
await authenticationPage.enterUsername('user');
await authenticationPage.enterEmail('[email protected]');
await authenticationPage.enterPassword('[email protected]');
await authenticationPage.checkAgreeTerms();
await authenticationPage.clickCreateAccount();
const text = await authenticationPage.getWelcomeMessageText();
expect(text).toEqual('Welcome back!');
});
});
30 changes: 30 additions & 0 deletions frontend/e2e/src/background-job-history.e2e-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { browser } from 'protractor';
import { BackgroundPage } from './pages/background-job-history.po';
import { loginAsUser } from './helpers/auth.helper';

describe('Navigate to Background Jobs and verify statuses of uploaded file', () => {
let background: BackgroundPage;

beforeAll(async () => {
background = new BackgroundPage();

await browser.waitForAngularEnabled(true);
await browser.driver.manage().window().maximize();
await loginAsUser('user', '[email protected]');
});

it('should open notifications and view background job details', async () => {

await background.openNotificationsDropdown();
await background.clickOnViewHistory();
await browser.waitForAngularEnabled(false);
await background.clickDetailsButton();
await background.verifyAnyValidStatusLabel();

const statusText = await background.getAnyValidStatusLabel().getText();
expect(['STATUS_LOCKED', 'STATUS_DONE']).toContain(statusText);
await background.closeDetailsModal();
const result = await background.isOnBackgroundJobHistory();
expect(result).toBe(true);
});
});
73 changes: 73 additions & 0 deletions frontend/e2e/src/dashboard.e2e-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { browser } from 'protractor';
import * as path from 'path';
import { DashboardPage } from './pages/dashboard.po';
import { loginAsUser } from './helpers/auth.helper';

jasmine.DEFAULT_TIMEOUT_INTERVAL = 120000;

describe('Dashboard Verify Medical Records', () => {
let dashboard: DashboardPage;

beforeAll(async () => {
dashboard = new DashboardPage();
await browser.driver.manage().window().maximize();
await browser.waitForAngularEnabled(true);
await loginAsUser('user', '[email protected]');

const filePath = path.resolve(__dirname, './data/example_client.json');
await dashboard.ensureDataOnDashboard(filePath);
});

it('should display user name in records', async () => {
const name = await dashboard.getUserNameOnly();
expect(name).toBeTruthy();
});

it('should list medical records dynamically', async () => {
const records = await dashboard.getAllRecordsText();
expect(records.length).toBeGreaterThan(0);
records.forEach(r => {
expect(r.trim().length).toBeGreaterThan(0);
});
});

it('should list all medical records and verify numbers exist', async () => {
const data = await dashboard.getAllRecordObjects();
expect(data.length).toBeGreaterThan(0);
data.forEach(item => {
expect(item.name).toBeTruthy(`Missing record name`);
expect(/\d+\s+Records/.test(item.records)).toBe(
true,
`Invalid records count format for ${item.name}: ${item.records}`
);
});
});

it('should extract all patient vitals and verify they have numeric values', async () => {
const vitals = await dashboard.getAllPatientVitals();
expect(vitals.length).toBeGreaterThan(0);
vitals.forEach(v => {
expect(v.title).toBeTruthy(`Vital has no title`);
const hasNumber = /\d+(\.\d+)?/.test(v.value);
expect(hasNumber).toBe(true, `Vital '${v.title}' is not numeric: ${v.value}`);
});
});

it('should verify Weight, Height and Blood Pressure vitals', async () => {
const weightText = await dashboard.getWeightFromCard();
const heightText = await dashboard.getHeightFromCard();
const bpText = await dashboard.getBloodPressureFromCard();

if (weightText) {
expect(/\d+(\.\d+)?/.test(weightText)).toBe(true, `Weight is not numeric: ${weightText}`);
}

if (heightText) {
expect(/\d+(\.\d+)?/.test(heightText)).toBe(true, `Height is not numeric: ${heightText}`);
}

if (bpText) {
expect(/\d+/.test(bpText)).toBe(true, `Blood Pressure is not numeric: ${bpText}`);
}
});
});
Loading