Skip to content

Commit 4c229a1

Browse files
authored
Playwright_RGP_Blood and RNA Kit Upload (#2183)
* RGP blood and rna kit upload playwright automation
1 parent 04e6d53 commit 4c229a1

File tree

6 files changed

+230
-1
lines changed

6 files changed

+230
-1
lines changed
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export enum KitTypeEnum {
22
SALIVA = 'SALIVA',
33
BLOOD = 'BLOOD',
4-
STOOL = 'STOOL'
4+
STOOL = 'STOOL',
5+
BLOOD_AND_RNA = 'BLOOD & RNA'
56
}

playwright-e2e/dsm/component/navigation/navigation.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {MiscellaneousEnum} from 'dsm/component/navigation/enums/miscellaneousNav
1515
import KitsSentPage from 'dsm/pages/kitsInfo-pages/kitsSentPage';
1616
import KitsReceivedPage from 'dsm/pages/kitsInfo-pages/kitsReceived-page/kitsReceivedPage';
1717
import TrackingScanPage from 'dsm/pages/scanner-pages/trackingScan-page';
18+
import RgpFinalScanPage from 'dsm/pages/scanner-pages/rgpFinalScan-page';
1819

1920

2021
type Selection = StudyNavEnum | StudyEnum | SamplesNavEnum | MiscellaneousEnum;
@@ -27,6 +28,7 @@ export class Navigation {
2728
[SamplesNavEnum.INITIAL_SCAN, new InitialScanPage(this.page)],
2829
[SamplesNavEnum.TRACKING_SCAN, new TrackingScanPage(this.page)],
2930
[SamplesNavEnum.FINAL_SCAN, new FinalScanPage(this.page)],
31+
[SamplesNavEnum.RGP_FINAL_SCAN, new RgpFinalScanPage(this.page)],
3032
[SamplesNavEnum.KIT_UPLOAD, new KitUploadPage(this.page)],
3133
[SamplesNavEnum.SENT, new KitsSentPage(this.page)],
3234
[SamplesNavEnum.RECEIVED, new KitsReceivedPage(this.page, this.request)],
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import {expect, Page, Locator} from '@playwright/test';
2+
3+
type inputField = 'Kit Label' | 'RNA' | 'DSM Label';
4+
5+
export default class RgpFinalScanPage {
6+
private readonly PAGE_TITLE = 'RGP Final Scan';
7+
8+
constructor(private readonly page: Page) {}
9+
10+
public async fillScanTrio(kitLabel: string, rna:string, dsmLabel: string, rowNumber: number): Promise<void> {
11+
//First check if the number row is valid
12+
const totalAmountOfRows = await this.getNumberOfScannableRows();
13+
expect(rowNumber, 'RGP Final Scan Page: More scannable rows displayed than expected').toBeLessThanOrEqual(totalAmountOfRows);
14+
15+
//Setup which row will be filled with info
16+
const kitLabelLocator = this.page.locator(`(//mat-form-field//input[contains(@data-placeholder, 'Kit Label')])[${rowNumber}]`);
17+
const rnaLocator = this.page.locator(`(//mat-form-field//input[contains(@data-placeholder, 'RNA')])[${rowNumber}]`);
18+
const dsmLabelLocator = this.page.locator(`(//mat-form-field//input[contains(@data-placeholder, 'DSM Label')])[${rowNumber}]`);
19+
20+
//Input info
21+
await kitLabelLocator.fill(kitLabel);
22+
await kitLabelLocator.blur();
23+
24+
await rnaLocator.fill(rna);
25+
await rnaLocator.blur();
26+
27+
await dsmLabelLocator.fill(dsmLabel);
28+
await dsmLabelLocator.blur();
29+
}
30+
31+
public async getNumberOfScannableRows(): Promise<number> {
32+
const numberOfRows = this.page.locator('//form/div').count();
33+
return numberOfRows;
34+
}
35+
36+
private getSaveScanPairsButton(): Locator {
37+
const scanPairButton = this.page.getByRole('button', { name: 'Save Scan Pairs' });
38+
return scanPairButton;
39+
}
40+
41+
public async save(): Promise<void> {
42+
const scanPairButton = this.getSaveScanPairsButton();
43+
await expect(scanPairButton, 'RGP Final Scan page - Save Scan Pairs button is not enabled like expected').toBeEnabled();
44+
await scanPairButton.focus();
45+
await scanPairButton.click();
46+
}
47+
48+
public async assertPageTitle(): Promise<void> {
49+
const heading = this.page.locator(`//h1[contains(., '${this.PAGE_TITLE}')]`);
50+
await expect(heading, 'RGP Final Scan page header is not visible').toBeVisible();
51+
}
52+
}
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
import { expect } from '@playwright/test';
2+
import { test } from 'fixtures/dsm-fixture';
3+
import { Navigation } from 'dsm/component/navigation/navigation';
4+
import Select from 'dss/component/select';
5+
import { KitUploadInfo } from 'dsm/pages/kitUpload-page/models/kitUpload-model';
6+
import {StudyEnum} from 'dsm/component/navigation/enums/selectStudyNav-enum';
7+
import { KitTypeEnum } from 'dsm/component/kitType/enums/kitType-enum';
8+
import ParticipantListPage from 'dsm/pages/participant-list-page';
9+
import {StudyNavEnum} from 'dsm/component/navigation/enums/studyNav-enum';
10+
import * as user from 'data/fake-user.json';
11+
import crypto from 'crypto';
12+
import KitUploadPage from 'dsm/pages/kitUpload-page/kitUpload-page';
13+
import {SamplesNavEnum} from 'dsm/component/navigation/enums/samplesNav-enum';
14+
import FamilyMemberTab from 'dsm/pages/participant-page/rgp/family-member-tab';
15+
import { FamilyMember } from 'dsm/component/tabs/enums/familyMember-enum';
16+
import KitsWithoutLabelPage from 'dsm/pages/kitsInfo-pages/kitsWithoutLabel-page';
17+
import {KitsColumnsEnum} from 'dsm/pages/kitsInfo-pages/enums/kitsColumns-enum';
18+
import KitsSentPage from 'dsm/pages/kitsInfo-pages/kitsSentPage';
19+
import KitsReceivedPage from 'dsm/pages/kitsInfo-pages/kitsReceived-page/kitsReceivedPage';
20+
import TrackingScanPage from 'dsm/pages/scanner-pages/trackingScan-page';
21+
import RgpFinalScanPage from 'dsm/pages/scanner-pages/rgpFinalScan-page'
22+
import { simplifyShortID } from 'utils/faker-utils';
23+
import { saveParticipantGuid } from 'utils/faker-utils';
24+
import { ParticipantListTable } from 'dsm/component/tables/participant-list-table';
25+
26+
test.describe('Blood & RNA Kit Upload', () => {
27+
test.skip('Verify that a blood & rna kit can be uploaded @rgp @functional @upload', async ({ page, request}, testInfo) => {
28+
const testResultDirectory = testInfo.outputDir;
29+
30+
const study = StudyEnum.RGP;
31+
const kitType = KitTypeEnum.BLOOD_AND_RNA;
32+
const expectedKitTypes = [KitTypeEnum.BLOOD, KitTypeEnum.BLOOD_AND_RNA]; //Later will be just Blood & RNA kit type for RGP
33+
34+
//Go into DSM
35+
const navigation = new Navigation(page, request);
36+
37+
//select RGP study
38+
await new Select(page, { label: 'Select study' }).selectOption('RGP');
39+
40+
//Go to recently created playwright test participant to get their short id
41+
const participantListPage = await navigation.selectFromStudy<ParticipantListPage>(StudyNavEnum.PARTICIPANT_LIST);
42+
await participantListPage.assertPageTitle();
43+
await participantListPage.waitForReady();
44+
45+
const participantListTable = new ParticipantListTable(page);
46+
const participantGuid = await participantListTable.getGuidOfMostRecentAutomatedParticipant(user.patient.firstName, true);
47+
saveParticipantGuid(participantGuid);
48+
49+
await participantListPage.filterListByParticipantGUID(user.patient.participantGuid);
50+
await participantListTable.openParticipantPageAt(0);
51+
52+
//For RGP, the short id needed for the kit upload is the family member's subject id
53+
const proband = new FamilyMemberTab(page, FamilyMember.PROBAND);
54+
proband.relationshipID = user.patient.relationshipID;
55+
56+
const probandTab = proband.getFamilyMemberTab();
57+
await expect(probandTab).toBeVisible();
58+
await probandTab.click();
59+
await expect(probandTab).toHaveClass('nav-link active');//Make sure the tab is in view and selected
60+
61+
const participantInfoSection = proband.getParticipantInfoSection();
62+
await participantInfoSection.click();
63+
64+
const probandSubjectID = proband.getSubjectID();
65+
await expect(probandSubjectID).not.toBeEmpty();
66+
const shortID = await probandSubjectID.inputValue();
67+
const simpleShortId = simplifyShortID(shortID, 'RGP');
68+
69+
//Deactivate existing kits for participant
70+
//Note: no blood kits are automatically created for RGP - preliminary deactivation of existing kits is done in case of prior test run
71+
const kitsWithoutLabelPage = await navigation.selectFromSamples<KitsWithoutLabelPage>(SamplesNavEnum.KITS_WITHOUT_LABELS);
72+
await kitsWithoutLabelPage.waitForLoad();
73+
await kitsWithoutLabelPage.assertPageTitle();
74+
await kitsWithoutLabelPage.selectKitType(kitType);
75+
await kitsWithoutLabelPage.assertCreateLabelsBtn();
76+
await kitsWithoutLabelPage.assertReloadKitListBtn();
77+
await kitsWithoutLabelPage.assertTableHeader();
78+
await kitsWithoutLabelPage.deactivateAllKitsFor(simpleShortId);
79+
80+
//The rest of the kit upload information - RGP kits are by family member instead of by account - using the proband's info to make a kit
81+
const kitUploadInfo = new KitUploadInfo(shortID, user.patient.firstName, user.patient.lastName);
82+
kitUploadInfo.street1 = user.patient.streetAddress;
83+
kitUploadInfo.city = user.patient.city;
84+
kitUploadInfo.postalCode = user.patient.zip;
85+
kitUploadInfo.state = user.patient.state.abbreviation;
86+
kitUploadInfo.country = user.patient.country.abbreviation;
87+
88+
//Upload a Blood & RNA kit
89+
const kitUploadPage = await navigation.selectFromSamples<KitUploadPage>(SamplesNavEnum.KIT_UPLOAD);
90+
await kitUploadPage.waitForLoad();
91+
await kitUploadPage.assertPageTitle();
92+
await kitUploadPage.assertDisplayedKitTypes(expectedKitTypes);
93+
await kitUploadPage.selectKitType(kitType);
94+
await kitUploadPage.assertBrowseBtn();
95+
await kitUploadPage.assertUploadKitsBtn();
96+
await kitUploadPage.assertInstructionSnapshot();
97+
await kitUploadPage.uploadFile(kitType, [kitUploadInfo], study, testResultDirectory);
98+
99+
//Go to Kits w/o Label to extract a shipping ID
100+
await navigation.selectFromSamples<KitsWithoutLabelPage>(SamplesNavEnum.KITS_WITHOUT_LABELS);
101+
await kitsWithoutLabelPage.waitForLoad();
102+
await kitsWithoutLabelPage.selectKitType(kitType);
103+
await kitsWithoutLabelPage.assertCreateLabelsBtn();
104+
await kitsWithoutLabelPage.assertReloadKitListBtn();
105+
await kitsWithoutLabelPage.assertTableHeader();
106+
await kitsWithoutLabelPage.assertPageTitle();
107+
108+
await kitsWithoutLabelPage.search(KitsColumnsEnum.SHORT_ID, simpleShortId);
109+
const shippingID = (await kitsWithoutLabelPage.getData(KitsColumnsEnum.SHIPPING_ID)).trim();
110+
111+
//Tracking scan
112+
const labelNumber = crypto.randomUUID().toString().substring(0, 10);
113+
const kitLabel = `RGP_${labelNumber}`;
114+
const trackingScanPage = await navigation.selectFromSamples<TrackingScanPage>(SamplesNavEnum.TRACKING_SCAN);
115+
await trackingScanPage.assertPageTitle();
116+
const trackingLabel = `tracking-${crypto.randomUUID().toString().substring(0, 10)}`;
117+
await trackingScanPage.fillScanPairs([trackingLabel, kitLabel]);
118+
await trackingScanPage.save();
119+
120+
//RGP final scan page - RNA labels must have the prefix 'RNA' (all caps)
121+
const finalScanPage = await navigation.selectFromSamples<RgpFinalScanPage>(SamplesNavEnum.RGP_FINAL_SCAN);
122+
const rnaNumber = crypto.randomUUID().toString().substring(0, 10);
123+
const rnaLabel = `RNA${rnaNumber}`;
124+
await finalScanPage.assertPageTitle();
125+
await finalScanPage.fillScanTrio(kitLabel, rnaLabel, shippingID, 1);
126+
await finalScanPage.save();
127+
128+
//Kits Sent Page
129+
const kitsSentPage = await navigation.selectFromSamples<KitsSentPage>(SamplesNavEnum.SENT);
130+
await kitsSentPage.waitForLoad();
131+
await kitsSentPage.assertPageTitle();
132+
await kitsSentPage.assertDisplayedKitTypes(expectedKitTypes);
133+
await kitsSentPage.selectKitType(kitType);
134+
135+
//Check for the sent blood kit
136+
await kitsSentPage.search(KitsColumnsEnum.MF_CODE, kitLabel);
137+
await kitsSentPage.assertDisplayedRowsCount(1);
138+
139+
//Check for the sent RNA kit
140+
await kitsSentPage.search(KitsColumnsEnum.MF_CODE, rnaLabel);
141+
await kitsSentPage.assertDisplayedRowsCount(1);
142+
143+
//Kits Received Page
144+
const kitsReceivedPage = await navigation.selectFromSamples<KitsReceivedPage>(SamplesNavEnum.RECEIVED);
145+
await kitsReceivedPage.waitForLoad();
146+
await kitsReceivedPage.assertPageTitle();
147+
await kitsReceivedPage.kitReceivedRequest(kitLabel); //Mark the blood kit as received
148+
await kitsReceivedPage.kitReceivedRequest(rnaLabel); //Mark the RNA kit as received
149+
await kitsReceivedPage.assertDisplayedKitTypes(expectedKitTypes);
150+
await kitsReceivedPage.selectKitType(kitType);
151+
152+
//Check for the received blood kit
153+
await kitsReceivedPage.search(KitsColumnsEnum.MF_CODE, kitLabel);
154+
await kitsReceivedPage.assertDisplayedRowsCount(1);
155+
156+
//Check for the received RNA kit
157+
await kitsReceivedPage.search(KitsColumnsEnum.MF_CODE, rnaLabel);
158+
await kitsReceivedPage.assertDisplayedRowsCount(1);
159+
});
160+
});

playwright-e2e/utils/faker-utils.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,17 @@ export const saveParticipantGuid = (guid: string) => {
4646
user.patient.participantGuid = guid;
4747
};
4848

49+
/**
50+
* Takes a short id that is presumed to have the study in it e.g. RGP_1234_56 and
51+
* returns the short id without the study name prefix e.g. 1234_56
52+
* @param shortId the short id
53+
* @param studyName the study name/alias used in the short id e.g. RGP
54+
* @returns simplified short id
55+
*/
56+
export const simplifyShortID = (shortId: string, studyName: string): string => {
57+
const shortIdParts = shortId.split(`${studyName}_`); // Use 'RGP_' to determine where to split
58+
const rgpPrefix = shortIdParts[0]; //RGP_ prefix
59+
const subjectID = shortIdParts[1]; //The subject id to be used as short id
60+
const simplifiedShortID = subjectID;
61+
return simplifiedShortID;
62+
}

0 commit comments

Comments
 (0)