Repository: HealthResearchAuthority/rsp-iras-qa
Pull request #35: RSP-1861_3670 - Automation scripts
Author: login: alfreddcruz-HRA
Created: 2025-05-20T08:33:03Z | Merged: 2025-05-23T13:16:53Z

## What was the purpose of this ticket?
RSP-1861_3670 - Automation scripts
For validating the RTS data for primary sponsor organisation in Key project roles page

## Jira Ref
[RSP-1861](https://nihr.atlassian.net/browse/RSP-1861)
[RSP-3670](https://nihr.atlassian.net/browse/RSP-3670)

## Type of Change

Put [X] inside the [] to make the box ticked

- [X] New Tests
- [X] Updating Tests
- [] Fixing Tests
- [] Framework Improvements
- [] Documentation

## Solution

What work was completed to cover off the story?
- Added scenarios in feature file for RSP-1861 and RSP-3670
- Added step definitions for the stories

## Checklist

Put [X] inside the [] to make the box ticked

- [X] Your code builds clean without any warnings, i.e. no ESLint or SonarCube errors
- [X] You have run the Pipeline jobs against this branch successfully
- [X] Any new or updated tests add value, i.e. provide correct assurances, fail when expected and log errors appropriately
- [X] Tests have been tagged appropriately
- [X] No duplicate tests, steps or functions have been added
- [X] You are using the correct naming conventions
- [X] Added files have been placed correctly within the projects folder structure
- [X] There is no dead code e.g. no "TODO" comments left, no unused imports etc
- [] Any Framework updates have been explained and demonstrated to the team



Diff:
diff --git a/.env-example b/.env-example
index 1d45b9654..09ff27c07 100644
--- a/.env-example
+++ b/.env-example
@@ -10,4 +10,5 @@ BROWSER='chromium' # 'chromium','safari','firefox','microsoft edge','google chro
 STEP_SCREENSHOT='no' # 'yes','no'
 SECRET_KEY='<Add secret key/encryption key here which is 32 character long>'
 AUTH_TAG='<Add Auth_Tag Value>'
-ADMIN_USER_PASS='<Add Encrypted Value>'
\ No newline at end of file
+ADMIN_USER_PASS='<Add Encrypted Value>'
+RTS_CLIENT_SECRET='<Add RTS client secret used for generating bearer token>'
\ No newline at end of file
diff --git a/src/hooks/CustomFixtures.ts b/src/hooks/CustomFixtures.ts
index 8aea9b6b9..093d662f0 100644
--- a/src/hooks/CustomFixtures.ts
+++ b/src/hooks/CustomFixtures.ts
@@ -45,6 +45,7 @@ import UserListReviewBodyPage from '../pages/IRAS/reviewResearch/userAdministrat
 import CheckRemoveUserReviewBodyPage from '../pages/IRAS/reviewResearch/userAdministration/manageReviewBodies/CheckRemoveUserReviewBodyPage';
 import SearchAddUserReviewBodyPage from '../pages/IRAS/reviewResearch/userAdministration/manageReviewBodies/SearchAddUserReviewBodyPage';
 import CheckAddUserReviewBodyPage from '../pages/IRAS/reviewResearch/userAdministration/manageReviewBodies/CheckAddUserReviewBodyPage';
+import RtsPage from '../pages/Common/RtsPage';
 
 type CustomFixtures = {
   commonItemsPage: CommonItemsPage;
@@ -91,6 +92,7 @@ type CustomFixtures = {
   checkRemoveUserReviewBodyPage: CheckRemoveUserReviewBodyPage;
   searchAddUserReviewBodyPage: SearchAddUserReviewBodyPage;
   checkAddUserReviewBodyPage: CheckAddUserReviewBodyPage;
+  rtsPage: RtsPage;
   makeAxeBuilder: () => AxeBuilder;
 };
 
@@ -271,6 +273,10 @@ export const test = base.extend<CustomFixtures>({
     await use(new CheckAddUserReviewBodyPage(page));
   },
 
+  rtsPage: async ({ page }, use) => {
+    await use(new RtsPage(page));
+  },
+
   makeAxeBuilder: async ({ page }, use) => {
     const makeAxeBuilder = () => new AxeBuilder({ page });
     await use(makeAxeBuilder);
diff --git a/src/pages/Common/RtsPage.ts b/src/pages/Common/RtsPage.ts
new file mode 100644
index 000000000..385007ea3
--- /dev/null
+++ b/src/pages/Common/RtsPage.ts
@@ -0,0 +1,81 @@
+import { Locator, Page } from '@playwright/test';
+import * as rtsPageTestData from '../../resources/test_data/common/rts_page_data.json';
+
+//Declare Page Objects
+export default class RtsPage {
+  readonly page: Page;
+  readonly rtsPageTestData: typeof rtsPageTestData;
+  readonly jsonDataPreLabel: Locator;
+  bearerToken: string;
+  rtsResponseList: string[] = [];
+
+  //Initialize Page Objects
+  constructor(page: Page) {
+    this.page = page;
+    this.rtsPageTestData = rtsPageTestData;
+
+    //Locators
+    this.jsonDataPreLabel = page.locator('pre');
+  }
+
+  //Page Methods
+  async authoriseRTS(request: any, dataset: any): Promise<string> {
+    const idgBaseUrl: string = dataset.idg_base_url;
+    const form = {
+      grant_type: dataset.grant_type,
+      scope: dataset.scope,
+      client_id: dataset.client_id,
+      client_secret: `${process.env.RTS_CLIENT_SECRET}`,
+    };
+    const headers = {
+      accept: dataset.accept,
+      'accept-encoding': dataset.accept_encoding,
+      'accept-language': dataset.accept_language,
+      'cache-control': dataset.cache_control,
+      'content-type': dataset.content_type,
+    };
+    const expectedAuthResponse = {
+      token_type: dataset.token_type,
+    };
+    try {
+      const authResponse = await (
+        await request.post(`${idgBaseUrl}oauth2/token`, {
+          form,
+          headers,
+        })
+      ).json();
+      const isGetTokenSuccessful = authResponse.token_type === expectedAuthResponse.token_type;
+      if (!isGetTokenSuccessful) {
+        console.error('ERROR: Get Auth Token Request Failed To Return a Bearer Token');
+        console.error(authResponse);
+        throw Error('REQUESTS WILL BE UNAUTHORIZED - STOPPING TEST EXECUTION');
+      } else {
+        this.bearerToken = 'Bearer ' + authResponse.access_token;
+      }
+    } catch (error) {
+      console.error(error);
+      const response = await request.post(`${idgBaseUrl}oauth2/token`, {
+        form,
+        headers,
+      });
+      console.error(response.headers());
+      console.error(await response.text());
+      throw Error('FAILURE! REQUESTS WILL BE UNAUTHORIZED - STOPPING TEST EXECUTION');
+    }
+    return this.bearerToken;
+  }
+
+  async executeRTSRequest(request: any, dataset: any, bearerToken: string, requestHeader: string): Promise<any> {
+    const requestResponse = await request.get(requestHeader, {
+      headers: {
+        accept: dataset.accept_encoding,
+        'accept-encoding': dataset.accept_encoding,
+        'accept-language': dataset.accept_language,
+        authorization: bearerToken,
+        'cache-control': dataset.cache_control,
+        'content-type': dataset.content_type_json,
+      },
+    });
+    return requestResponse;
+  }
+}
diff --git a/src/pages/IRAS/makeChanges/KeyProjectRolesPage.ts b/src/pages/IRAS/makeChanges/KeyProjectRolesPage.ts
index 25609613b..3e1ad4793 100644
--- a/src/pages/IRAS/makeChanges/KeyProjectRolesPage.ts
+++ b/src/pages/IRAS/makeChanges/KeyProjectRolesPage.ts
@@ -15,6 +15,10 @@ export default class KeyProjectRolesPage {
   readonly chief_investigator_email_text_summary_error_label: Locator;
   readonly sponsor_contact_email_text_summary_error_label: Locator;
   readonly primary_sponsor_organisation_text: Locator;
+  readonly primary_sponsor_organisation_header_label: Locator;
+  readonly primary_sponsor_organisation_jsenabled_text: Locator;
+  readonly primary_sponsor_organisation_suggestion_list_labels: Locator;
+  readonly primary_sponsor_organisation_suggestion_listbox: Locator;
 
   //Initialize Page Objects
   constructor(page: Page) {
@@ -24,22 +28,24 @@ export default class KeyProjectRolesPage {
     //Locators
     this.pageHeading = this.page.getByTestId('title');
     this.chief_investigator_header_label = this.page.locator('label[for="IQA0311_Text"]');
-    this.chief_investigator_email_label = this.page
-      .locator('label[for="IQA0311_Text"]')
-      .locator('..')
-      .locator('..')
-      .locator('div[id="rule-hint"]');
+    this.chief_investigator_email_label = this.page.getByTestId('chief-investigator-hint');
     this.sponsor_contact_header_label = this.page.locator('label[for="IQA0313_Text"]');
-    this.sponsor_contact_email_label = this.page
-      .locator('label[for="IQA0313_Text"]')
-      .locator('..')
-      .locator('..')
-      .locator('div[id="rule-hint"]');
+    this.sponsor_contact_email_label = this.page.getByTestId('sponsor-contact-hint');
     this.chief_investigator_email_text = this.page.getByTestId('IQA0311_Text');
     this.sponsor_contact_email_text = this.page.getByTestId('IQA0313_Text');
     this.chief_investigator_email_text_summary_error_label = this.page.locator('a[href="#Questions[0].AnswerText"]');
     this.sponsor_contact_email_text_summary_error_label = this.page.locator('a[href="#Questions[1].AnswerText"]');
     this.primary_sponsor_organisation_text = this.page.getByTestId('IQA0312_Text');
+    this.primary_sponsor_organisation_header_label = this.page.locator('label[for="IQA0312_Text"]');
+    this.primary_sponsor_organisation_jsenabled_text = this.page.getByRole('combobox', {
+      name: keyProjectRolesPageTestData.Label_Texts.primary_sponsor_organisation_header_label,
+    });
+    this.primary_sponsor_organisation_suggestion_list_labels = this.primary_sponsor_organisation_jsenabled_text
+      .locator('..')
+      .getByRole('option');
+    this.primary_sponsor_organisation_suggestion_listbox = this.primary_sponsor_organisation_jsenabled_text
+      .locator('..')
+      .getByRole('listbox');
   }
 
   //Page Methods
diff --git a/src/pages/IRAS/makeChanges/MyResearchProjectsPage.ts b/src/pages/IRAS/makeChanges/MyResearchProjectsPage.ts
index 16b96530f..6e702ad20 100644
--- a/src/pages/IRAS/makeChanges/MyResearchProjectsPage.ts
+++ b/src/pages/IRAS/makeChanges/MyResearchProjectsPage.ts
@@ -22,7 +22,7 @@ export default class MyResearchProjectsPage {
 
   //Page Methods
   async goto() {
-    await this.page.goto('');
+    await this.page.goto('/application/welcome/');
   }
 
   async assertOnMyResearchProjectsPage() {
diff --git a/src/pages/IRAS/makeChanges/ReviewYourAnswersPage.ts b/src/pages/IRAS/makeChanges/ReviewYourAnswersPage.ts
index 4d274b653..26719f780 100644
--- a/src/pages/IRAS/makeChanges/ReviewYourAnswersPage.ts
+++ b/src/pages/IRAS/makeChanges/ReviewYourAnswersPage.ts
@@ -43,6 +43,7 @@ export default class ReviewYourAnswersPage {
   readonly primary_sponsor_organisation_row: Locator;
   readonly primary_sponsor_organisation_text: Locator;
   readonly primary_sponsor_organisation_change_link: Locator;
+  readonly primary_sponsor_orgainisation_enter_link: Locator;
 
   //Initialize Page Objects
   constructor(page: Page) {
@@ -141,6 +142,9 @@ export default class ReviewYourAnswersPage {
     this.primary_sponsor_organisation_change_link = this.primary_sponsor_organisation_row.getByText(
       this.linkTextData.Review_Your_Answers_Page.Change
     );
+    this.primary_sponsor_orgainisation_enter_link = this.primary_sponsor_organisation_text.getByText(
+      this.reviewYourAnswersPageTestData.Review_Your_Answers_Page.primary_sponsor_orgainisation_enter_link
+    );
   }
 
   //Page Methods
@@ -164,6 +168,9 @@ export default class ReviewYourAnswersPage {
       case 'chief_investigator':
         await this.chief_investigator_email_change_link.click();
         break;
+      case 'primary_sponsor_organisation':
+        await this.primary_sponsor_organisation_change_link.click();
+        break;
       case 'sponsor_contact':
         await this.sponsor_contact_email_change_link.click();
         break;
@@ -192,6 +199,9 @@ export default class ReviewYourAnswersPage {
       case 'chief_investigator':
         await this.chief_investigator_email_enter_link.click();
         break;
+      case 'primary_sponsor_organisation':
+        await this.primary_sponsor_orgainisation_enter_link.click();
+        break;
       case 'sponsor_contact':
         await this.sponsor_contact_email_enter_link.click();
         break;
diff --git a/src/resources/test_data/common/rts_page_data.json b/src/resources/test_data/common/rts_page_data.json
new file mode 100644
index 000000000..33bc12704
--- /dev/null
+++ b/src/resources/test_data/common/rts_page_data.json
@@ -0,0 +1,86 @@
+{
+  "RTS_NIHR_FHIR_Config": {
+    "idg_base_url": "https://test.id.nihr.ac.uk/",
+    "grant_type": "client_credentials",
+    "scope": "openid+profile+email",
+    "client_id": "aaU7PY4hz_x_RVOyCo09CulPbTca",
+    "accept": "application/json",
+    "accept_encoding": "gzip, deflate, br",
+    "accept_language": "en-GB,en-US;q=0.9,en;q=0.8",
+    "cache_control": "no-cache",
+    "content_type": "application/x-www-form-urlencoded",
+    "token_type": "Bearer"
+  },
+  "RTS_Active_Sponsor_Organisation_NHS": {
+    "rts_base_url": "https://test.fhir.rts.nihr.ac.uk/api/",
+    "content_type_json": "application/json",
+    "organisation_name": "nhs",
+    "active": true,
+    "role": "CRSPNSR@2.16.840.1.113883.5.110",
+    "count": "1000",
+    "offset": "3000"
+  },
+  "RTS_Active_Sponsor_Organisation_MAN": {
+    "rts_base_url": "https://test.fhir.rts.nihr.ac.uk/api/",
+    "content_type_json": "application/json",
+    "organisation_name": "man",
+    "active": true,
+    "role": "CRSPNSR@2.16.840.1.113883.5.110",
+    "count": "1000",
+    "offset": "3000"
+  },
+  "RTS_Active_Sponsor_Organisation_Brackets": {
+    "rts_base_url": "https://test.fhir.rts.nihr.ac.uk/api/",
+    "content_type_json": "application/json",
+    "organisation_name": "(Sp",
+    "active": true,
+    "role": "CRSPNSR@2.16.840.1.113883.5.110",
+    "count": "1000",
+    "offset": "3000"
+  },
+  "RTS_Active_Sponsor_Organisation_Dot_Comma": {
+    "rts_base_url": "https://test.fhir.rts.nihr.ac.uk/api/",
+    "content_type_json": "application/json",
+    "organisation_name": ".,L",
+    "active": true,
+    "role": "CRSPNSR@2.16.840.1.113883.5.110",
+    "count": "1000",
+    "offset": "3000"
+  },
+  "RTS_Active_Sponsor_Organisation_Slash": {
+    "rts_base_url": "https://test.fhir.rts.nihr.ac.uk/api/",
+    "content_type_json": "application/json",
+    "organisation_name": "A/S",
+    "active": true,
+    "role": "CRSPNSR@2.16.840.1.113883.5.110",
+    "count": "1000",
+    "offset": "3000"
+  },
+  "RTS_Active_Sponsor_Organisation_Hyphen": {
+    "rts_base_url": "https://test.fhir.rts.nihr.ac.uk/api/",
+    "content_type_json": "application/json",
+    "organisation_name": "e-T",
+    "active": true,
+    "role": "CRSPNSR@2.16.840.1.113883.5.110",
+    "count": "1000",
+    "offset": "3000"
+  },
+  "RTS_Active_Sponsor_Organisation_Start_Space": {
+    "rts_base_url": "https://test.fhir.rts.nihr.ac.uk/api/",
+    "content_type_json": "application/json",
+    "organisation_name": " nh",
+    "active": true,
+    "role": "CRSPNSR@2.16.840.1.113883.5.110",
+    "count": "1000",
+    "offset": "3000"
+  },
+  "RTS_Active_Sponsor_Organisation_Ends_Space": {
+    "rts_base_url": "https://test.fhir.rts.nihr.ac.uk/api/",
+    "content_type_json": "application/json",
+    "organisation_name": "hs ",
+    "active": true,
+    "role": "CRSPNSR@2.16.840.1.113883.5.110",
+    "count": "1000",
+    "offset": "3000"
+  }
+}
\ No newline at end of file
diff --git a/src/resources/test_data/iras/make_changes/key_project_roles_data.json b/src/resources/test_data/iras/make_changes/key_project_roles_data.json
index e2324e537..c271aca91 100644
--- a/src/resources/test_data/iras/make_changes/key_project_roles_data.json
+++ b/src/resources/test_data/iras/make_changes/key_project_roles_data.json
@@ -5,6 +5,7 @@
   "Label_Texts": {
     "chief_investigator_header_label": "Chief Investigator",
     "chief_investigator_email_label": "Email",
+    "primary_sponsor_organisation_header_label": "Primary sponsor organisation",
     "sponsor_contact_header_label": "Sponsor contact",
     "sponsor_contact_email_label": "Email"
   },
@@ -152,6 +153,48 @@
     "chief_investigator_email_text": "Johndoe2@example.com",
     "sponsor_contact_email_text": "Johndoe2@example.com"
   },
+  "Sponsor_Organisation_Partial_Text_NHS": {
+    "primary_sponsor_organisation_text": "nhs"
+  },
+  "Sponsor_Organisation_Full_Text_Aalborg": {
+    "primary_sponsor_organisation_text": "Aalborg University Hospital"
+  },
+  "Sponsor_Organisation_Text_Blank": {
+    "primary_sponsor_organisation_text": ""
+  },
+  "Sponsor_Organisation_Text_Partial_Brackets": {
+    "primary_sponsor_organisation_text": "(Sp"
+  },
+  "Sponsor_Organisation_Text_Partial_Dot_Comma": {
+    "primary_sponsor_organisation_text": ".,L"
+  },
+  "Sponsor_Organisation_Text_Partial_Slash": {
+    "primary_sponsor_organisation_text": "A/S"
+  },
+  "Sponsor_Organisation_Text_Partial_Hyphen": {
+    "primary_sponsor_organisation_text": "e-T"
+  },
+  "Sponsor_Organisation_Text_Partial_Start_Space": {
+    "primary_sponsor_organisation_text": " nh"
+  },
+  "Sponsor_Organisation_Text_Partial_End_Space": {
+    "primary_sponsor_organisation_text": "hs "
+  },
+  "Sponsor_Organisation_Text_Brackets": {
+    "primary_sponsor_organisation_text": "L'Institut d'Investigacions Biomediques August Pi i Sunyer (IDIBAPS) (Spain)"
+  },
+  "Sponsor_Organisation_Text_Amp": {
+    "primary_sponsor_organisation_text": "L. MOLTENI & C. DEI FRATELLI ALITTI - SOCIETA' DI ESERCIZIO - S.P.A."
+  },
+  "Sponsor_Organisation_Text_Dot_Comma": {
+    "primary_sponsor_organisation_text": "Eisai Co.,Ltd."
+  },
+  "Sponsor_Organisation_Text_Slash": {
+    "primary_sponsor_organisation_text": "Y-mAbs Therapeutics A/S"
+  },
+  "Sponsor_Organisation_Text_Hyphen": {
+    "primary_sponsor_organisation_text": "e-Therapeutics"
+  },
   "Invalid_Email_Data_One_Start_With_Dot": {
     "chief_investigator_email_text": ".john@example.com"
   },
@@ -301,5 +344,17 @@
   },
   "Invalid_Email_Data_Two_Max_Char": {
     "sponsor_contact_email_text": "EmailAddressThatExceeds320CharactersEmailAddressThatExceeds320CharactersEmailAddressThatExceeds320CharactersEmailAddressThatExceeds320CharactersEmailAddressThatExceeds320CharactersEmailAddressThatExceeds320CharactersEmailAddressThatExceeds320CharactersEmailAddressThatExceeds320CharactersEmailAddressThatExcee@example.com"
+  },
+  "Sponsor_Organisation_Invalid_Data": {
+    "primary_sponsor_organisation_text": "test invalid data"
+  },
+  "Sponsor_Organisation_Min_Char": {
+    "primary_sponsor_organisation_text": "nh"
+  },
+  "Suggestion_List_Common_Headers": {
+    "suggestion_header": "Suggestions",
+    "suggestion_footer": "Continue entering to improve suggestions",
+    "continue_entering_suggestion": "Continue entering to get suggestions",
+    "no_suggestion_found": "No suggestions found."
   }
 }
diff --git a/src/resources/test_data/iras/make_changes/review_your_answers_data.json b/src/resources/test_data/iras/make_changes/review_your_answers_data.json
index 18ea4e5d2..fd2c53cfb 100644
--- a/src/resources/test_data/iras/make_changes/review_your_answers_data.json
+++ b/src/resources/test_data/iras/make_changes/review_your_answers_data.json
@@ -13,6 +13,7 @@
     "primary_sponsor_organisation_label": "Primary sponsor organisation",
     "sponsor_contact_email_label": "Sponsor contact",
     "sponsor_contact_email_enter_link": "Enter sponsor contact",
+    "primary_sponsor_orgainisation_enter_link": "Enter primary sponsor organisation",
     "research_locations_sub_heading": "Research locations",
     "participating_nations_label": "Participating nations",
     "nations_participating_enter_link": "Enter participating nations",
diff --git a/src/steps/Common/RtsSteps.ts b/src/steps/Common/RtsSteps.ts
new file mode 100644
index 000000000..6aa930832
--- /dev/null
+++ b/src/steps/Common/RtsSteps.ts
@@ -0,0 +1,72 @@
+import { createBdd } from 'playwright-bdd';
+import { test, expect } from '../../hooks/CustomFixtures';
+import { confirmStringNotNull, sortArray } from '../../utils/UtilFunctions';
+
+const { When, Then } = createBdd(test);
+
+When('I authorise the rts api using {string}', async ({ request, rtsPage }, datasetName: string) => {
+  const dataset = rtsPage.rtsPageTestData[datasetName];
+  await rtsPage.authoriseRTS(request, dataset);
+});
+
+Then(
+  'I make a request to the rts api using {string} dataset for sponsor organisation',
+  async ({ request, rtsPage }, datasetName: string) => {
+    const dataset = rtsPage.rtsPageTestData[datasetName];
+    const rtsBaseUrl: string = dataset.rts_base_url;
+    const organisationName = dataset.organisation_name;
+    const active = dataset.active;
+    const role = dataset.role;
+    const count = dataset.count;
+    const offset = dataset.offset;
+    for (let offsetCount = 0; offsetCount <= offset; ) {
+      const requestHeader =
+        `${rtsBaseUrl}organization?` +
+        `name:contains=` +
+        organisationName +
+        `&NihrRoleIdentifier=` +
+        role +
+        `&_count=` +
+        count +
+        `&_offset=` +
+        offsetCount;
+      const requestResponse = await rtsPage.executeRTSRequest(request, dataset, rtsPage.bearerToken, requestHeader);
+      await expect(requestResponse).toBeOK();
+      const receivedJson = await requestResponse.json();
+      if (typeof receivedJson.entry !== 'undefined') {
+        receivedJson.entry.forEach((element) => {
+          if (element.resource.active === active) {
+            rtsPage.rtsResponseList.push(element.resource.name);
+          }
+        });
+      } else {
+        break;
+      }
+      offsetCount = offsetCount + 1000;
+    }
+  }
+);
+
+Then(
+  'I validate the list of sponsor organisations retrieved in ui compared to the rts response received using {string}',
+  async ({ rtsPage }, datasetName: string) => {
+    const dataset = rtsPage.rtsPageTestData[datasetName];
+    const applicationUrl: string = `${process.env.BASE_URL}`;
+    const organisationName = dataset.organisation_name;
+    const role = dataset.role;
+    const offset = dataset.offset;
+    const newApplicationURL =
+      `${applicationUrl}Organisation/GetOrganisations?` +
+      `name=` +
+      organisationName +
+      `&role=` +
+      role +
+      `&pageSize=` +
+      offset;
+    await rtsPage.page.goto(newApplicationURL);
+    const rtsDataFromApplication = confirmStringNotNull(await rtsPage.jsonDataPreLabel.textContent());
+    const rtsDataFromApplicationJSONActual = await sortArray(JSON.parse(rtsDataFromApplication));
+    const rtsResponseDataExpected = await sortArray(rtsPage.rtsResponseList);
+    expect(rtsDataFromApplicationJSONActual).toEqual(rtsResponseDataExpected);
+  }
+);
diff --git a/src/steps/IRAS/makeChanges/KeyProjectRolesSteps.ts b/src/steps/IRAS/makeChanges/KeyProjectRolesSteps.ts
index 9eb4d1ecc..4d1eeffdd 100644
--- a/src/steps/IRAS/makeChanges/KeyProjectRolesSteps.ts
+++ b/src/steps/IRAS/makeChanges/KeyProjectRolesSteps.ts
@@ -1,5 +1,6 @@
 import { createBdd } from 'playwright-bdd';
 import { expect, test } from '../../../hooks/CustomFixtures';
+import { sortArray } from '../../../utils/UtilFunctions';
 
 const { Then } = createBdd(test);
 
@@ -9,11 +10,25 @@ Then('I can see the key project roles page', async ({ keyProjectRolesPage }) =>
 
 Then(
   'I fill the key project roles page with {string}',
-  async ({ commonItemsPage, keyProjectRolesPage }, datasetName: string) => {
+  async ({ commonItemsPage, keyProjectRolesPage, $tags }, datasetName: string) => {
     const dataset = keyProjectRolesPage.keyProjectRolesPageTestData[datasetName];
     for (const key in dataset) {
       if (Object.prototype.hasOwnProperty.call(dataset, key)) {
-        await commonItemsPage.fillUIComponent(dataset, key, keyProjectRolesPage);
+        if (key === 'primary_sponsor_organisation_text' && $tags.includes('@jsEnabled')) {
+          dataset['primary_sponsor_organisation_jsenabled_text'] = dataset['primary_sponsor_organisation_text'];
+          await commonItemsPage.fillUIComponent(
+            dataset,
+            'primary_sponsor_organisation_jsenabled_text',
+            keyProjectRolesPage
+          );
+          await keyProjectRolesPage.page.waitForTimeout(2000);
+          if (await keyProjectRolesPage.primary_sponsor_organisation_suggestion_list_labels.first().isVisible()) {
+            await keyProjectRolesPage.primary_sponsor_organisation_suggestion_list_labels.first().click();
+          }
+          delete dataset['primary_sponsor_organisation_jsenabled_text'];
+        } else {
+          await commonItemsPage.fillUIComponent(dataset, key, keyProjectRolesPage);
+        }
       }
     }
   }
@@ -67,3 +82,66 @@ Then(
     }
   }
 );
+
+Then(
+  'I type valid {string} for primary sponsor organisation suggestion box and validate the suggestion list along with {string}',
+  async ({ keyProjectRolesPage, rtsPage }, datasetName: string, suggestionCommonDatasetName) => {
+    const dataset = keyProjectRolesPage.keyProjectRolesPageTestData[datasetName];
+    const suggestionHeadersDatasetName = keyProjectRolesPage.keyProjectRolesPageTestData[suggestionCommonDatasetName];
+    let sponsorOrganisationNameListExpected = await sortArray(rtsPage.rtsResponseList);
+    if (sponsorOrganisationNameListExpected.length > 5) {
+      sponsorOrganisationNameListExpected = sponsorOrganisationNameListExpected.slice(0, 5);
+    }
+    await keyProjectRolesPage.primary_sponsor_organisation_jsenabled_text.fill(
+      dataset['primary_sponsor_organisation_text']
+    );
+    await keyProjectRolesPage.page.waitForTimeout(2000);
+    const sponsorOrganisationNameListActual =
+      await keyProjectRolesPage.primary_sponsor_organisation_suggestion_list_labels.allTextContents();
+    expect(sponsorOrganisationNameListActual).toEqual(sponsorOrganisationNameListExpected);
+    const suggestionsHeaderLabelActual = await keyProjectRolesPage.primary_sponsor_organisation_suggestion_listbox
+      .first()
+      .getAttribute('data-before-suggestions');
+    const suggestionsHeaderLabelExpected = suggestionHeadersDatasetName.suggestion_header;
+    expect(suggestionsHeaderLabelActual).toEqual(suggestionsHeaderLabelExpected);
+    const suggestionsFooterLabelActual = await keyProjectRolesPage.primary_sponsor_organisation_suggestion_listbox
+      .first()
+      .getAttribute('data-after-suggestions');
+    const suggestionsFooterLabelExpected = suggestionHeadersDatasetName.suggestion_footer;
+    expect(suggestionsFooterLabelActual).toEqual(suggestionsFooterLabelExpected);
+  }
+);
+
+Then(
+  'I type invalid {string} for primary sponsor organisation suggestion box and validate the suggestion list along with {string}',
+  async ({ keyProjectRolesPage }, datasetName: string, suggestionCommonDatasetName) => {
+    const dataset = keyProjectRolesPage.keyProjectRolesPageTestData[datasetName];
+    const suggestionHeadersDatasetName = keyProjectRolesPage.keyProjectRolesPageTestData[suggestionCommonDatasetName];
+    await keyProjectRolesPage.primary_sponsor_organisation_jsenabled_text.fill(
+      dataset['primary_sponsor_organisation_text']
+    );
+    await keyProjectRolesPage.page.waitForTimeout(2000);
+    const noResultFoundSuggestionActual = await keyProjectRolesPage.primary_sponsor_organisation_suggestion_list_labels
+      .first()
+      .textContent();
+    const suggestionsHeaderLabelExpected = suggestionHeadersDatasetName.no_suggestion_found;
+    expect(noResultFoundSuggestionActual).toEqual(suggestionsHeaderLabelExpected);
+  }
+);
+
+Then(
+  'I type min characters {string} for primary sponsor organisation suggestion box and validate the suggestion list along with {string}',
+  async ({ keyProjectRolesPage }, datasetName: string, suggestionCommonDatasetName) => {
+    const dataset = keyProjectRolesPage.keyProjectRolesPageTestData[datasetName];
+    const suggestionHeadersDatasetName = keyProjectRolesPage.keyProjectRolesPageTestData[suggestionCommonDatasetName];
+    await keyProjectRolesPage.primary_sponsor_organisation_jsenabled_text.fill(
+      dataset['primary_sponsor_organisation_text']
+    );
+    await keyProjectRolesPage.page.waitForTimeout(2000);
+    const continueEnteringSuggestionActual = await keyProjectRolesPage.primary_sponsor_organisation_suggestion_listbox
+      .first()
+      .getAttribute('data-before-suggestions');
+    const suggestionsHeaderLabelExpected = suggestionHeadersDatasetName.suggestion_footer;
+    expect(continueEnteringSuggestionActual).toEqual(suggestionsHeaderLabelExpected);
+  }
+);
diff --git a/src/utils/UtilFunctions.ts b/src/utils/UtilFunctions.ts
index 74eafd082..87800ce1d 100644
--- a/src/utils/UtilFunctions.ts
+++ b/src/utils/UtilFunctions.ts
@@ -437,3 +437,7 @@ export async function returnSingleRandomLocator(resolvesToMultiElements: Locator
   const randomIndex = Math.floor(Math.random() * (noOfElements - 1));
   return resolvesToMultiElements.nth(randomIndex);
 }
+
+export async function sortArray(value: string[]): Promise<string[]> {
+  return value.sort((a, b) => a.localeCompare(b, undefined, { sensitivity: 'base' }));
+}
diff --git a/tests/features/cross-compatible/accessibility/AxeAccessibility.feature b/tests/features/cross-compatible/accessibility/AxeAccessibility.feature
index 86b0d8191..23b4e8f5b 100644
--- a/tests/features/cross-compatible/accessibility/AxeAccessibility.feature
+++ b/tests/features/cross-compatible/accessibility/AxeAccessibility.feature
@@ -339,7 +339,6 @@ Feature: Run Axe Accessibilty Test Tool Against App Pages
     And I analyse the results from the Axe scan
     Then I expect to receive no WCAG Violations
 
-
   @axeAccessibilityConfirmReviewBodies @adminUser @axeAccessibilityManageReviewBodies
   Scenario Outline: Create review body confirmation page
     Given I have navigated to the 'Manage_Review_Bodies_Page'
@@ -650,7 +649,7 @@ Feature: Run Axe Accessibilty Test Tool Against App Pages
     And I analyse the results from the Axe scan
     Then I expect to receive no WCAG Violations
 
-  @axeAccessibilityReviewBodyUserListSearchNoResultsFound  @axeAccessibilityReviewBodyUserList @adminUser @axeAccessibilityManageReviewBodies
+  @axeAccessibilityReviewBodyUserListSearchNoResultsFound @axeAccessibilityReviewBodyUserList @adminUser @axeAccessibilityManageReviewBodies
   Scenario: View user list page of the review body when search results not found
     Given I have navigated to the 'System_Administration_Page'
     And I click the 'Manage_Review_Bodies' link on the 'System_Administration_Page'
@@ -768,4 +767,18 @@ Feature: Run Axe Accessibilty Test Tool Against App Pages
     And I am on the confirmation screen
     When I Scan the page with the Axe Accessibilty Tool
     And I analyse the results from the Axe scan
-    Then I expect to receive no WCAG Violations
\ No newline at end of file
+    Then I expect to receive no WCAG Violations
+
+  @axeAccessibilityKeyProjectRolesSponsorOrganisation @adminUser
+  Scenario: Key Project Roles - Primary Sponsor Organisation Suggestion List
+    Given I have navigated to the my research projects page
+    And I click the 'Create_Project_Record' button on the 'My_Research_Projects_Page'
+    When I click the 'Start' button on the 'Create_Project_Record_Page'
+    And I fill the unique iras id in project details iras page
+    When I click the 'Save_Continue' button on the 'Project_Details_IRAS_Page'
+    When I click the 'Save_Continue' button on the 'Project_Details_Title_Page'
+    Then I can see the key project roles page
+    And I fill the key project roles page with 'Sponsor_Organisation_Partial_Text_NHS'
+    When I Scan the page with the Axe Accessibilty Tool
+    And I analyse the results from the Axe scan
+    Then I expect to receive no WCAG Violations
diff --git a/tests/features/cross-compatible/stories/regressionTests/CreateProject.feature b/tests/features/cross-compatible/stories/regressionTests/CreateProject.feature
index 40e4261fb..9c5407324 100644
--- a/tests/features/cross-compatible/stories/regressionTests/CreateProject.feature
+++ b/tests/features/cross-compatible/stories/regressionTests/CreateProject.feature
@@ -219,3 +219,20 @@ Feature: Create Amendment - Create Project - Regression Tests
     Examples:
       | Navigation_Button_First | Navigation_Button_Second | Project_Details_IRAS | Navigation_Button_Third | Validation_Text | Project_Details_Title | Key_Project_Roles     | Research_Locations   |
       | Create_Project_Record   | Start                    | Valid_IRAS_ID_Min    | Save_Continue           | Label_Texts     | Valid_Data_All_Fields | Valid_Data_All_Fields | Data_With_No_NHS_HSC |
+
+  @CreateProjectRTSRegression @jsEnabled
+  Scenario Outline: Validate the active primary sponsor organisation from rts with data in database
+    When I authorise the rts api using '<RTS_API_Data>'
+    Then I make a request to the rts api using '<RTS_Request>' dataset for sponsor organisation
+    And I validate the list of sponsor organisations retrieved in ui compared to the rts response received using '<RTS_Request>'
+
+    Examples:
+      | RTS_API_Data         | RTS_Request                                 |
+      | RTS_NIHR_FHIR_Config | RTS_Active_Sponsor_Organisation_NHS         |
+      | RTS_NIHR_FHIR_Config | RTS_Active_Sponsor_Organisation_MAN         |
+      | RTS_NIHR_FHIR_Config | RTS_Active_Sponsor_Organisation_Brackets    |
+      | RTS_NIHR_FHIR_Config | RTS_Active_Sponsor_Organisation_Dot_Comma   |
+      | RTS_NIHR_FHIR_Config | RTS_Active_Sponsor_Organisation_Slash       |
+      | RTS_NIHR_FHIR_Config | RTS_Active_Sponsor_Organisation_Hyphen      |
+      | RTS_NIHR_FHIR_Config | RTS_Active_Sponsor_Organisation_Start_Space |
+      | RTS_NIHR_FHIR_Config | RTS_Active_Sponsor_Organisation_Ends_Space  |
diff --git a/tests/features/cross-compatible/stories/systemTests/makeChanges/CreateProject.feature b/tests/features/cross-compatible/stories/systemTests/makeChanges/CreateProject.feature
index b4efe4cf3..fa69eb286 100644
--- a/tests/features/cross-compatible/stories/systemTests/makeChanges/CreateProject.feature
+++ b/tests/features/cross-compatible/stories/systemTests/makeChanges/CreateProject.feature
@@ -344,7 +344,7 @@ Feature: Create Amendment - Create Project
     And I fill the unique iras id in project details iras page
     And I click the 'Save_Continue' button on the 'Project_Details_IRAS_Page'
     Then I can see the project details title page
-    And  I have navigated to the my research projects page
+    And I have navigated to the my research projects page
     And I can see the my research projects page
     And I click the 'Create_Project_Record' button on the 'My_Research_Projects_Page'
     And I click the 'Start' button on the 'Create_Project_Record_Page'
@@ -357,7 +357,6 @@ Feature: Create Amendment - Create Project
       | Project_Details_IRAS      | Field_And_Summary_Error_Message       |
       | Invalid_IRAS_ID_Duplicate | Field_Error_Message_Iras_Id_Duplicate |
 
-
   @rsp-1863 @saveLaterProjectTitle
   Scenario Outline: Verify product details are saved when user saves the record on create project - Project details page
     And I click the 'Create_Project_Record' button on the 'My_Research_Projects_Page'
@@ -428,7 +427,7 @@ Feature: Create Amendment - Create Project
     And I fill the project details title page with '<Project_Details_Title>'
     And I capture the page screenshot
     When I click the 'Save_Continue' button on the 'Project_Details_Title_Page'
-    And  I fill the key project roles page with '<Key_Project_Roles>'
+    And I fill the key project roles page with '<Key_Project_Roles>'
     And I capture the page screenshot
     And I click the 'Save_Continue' button on the 'Key_Project_Roles_Page'
     And I fill the research locations page with '<Research_Locations>'
@@ -483,7 +482,6 @@ Feature: Create Amendment - Create Project
       | Invalid_Date_No_Month                       | Date_Month_Field_Error_Message  |
       | Invalid_Date_No_Year                        | Date_Year_Field_Error_Message   |
 
-
   @rsp-1863 @saveLaterChiefInvEmailValidations
   Scenario Outline: Validate error messages when user saves the project with invalid Chief Investigator email data on key project roles page
     And I click the 'Create_Project_Record' button on the 'My_Research_Projects_Page'
@@ -497,7 +495,7 @@ Feature: Create Amendment - Create Project
     And I can see the key project roles page
     Then I fill the key project roles page with '<Key_Project_Roles>'
     And I capture the page screenshot
-    And  I click the 'Save_For_Later' button on the 'Key_Project_Roles_Page'
+    And I click the 'Save_For_Later' button on the 'Key_Project_Roles_Page'
     Then I validate '<Field_And_Summary_Error_Message>' displayed on 'Key_Project_Roles_Page'
     And I capture the page screenshot
 
@@ -529,7 +527,6 @@ Feature: Create Amendment - Create Project
       | Valid_Data_All_Fields | Invalid_Email_Data_One_Punycode                        | Field_Error_Chief_Email         |
       | Valid_Data_All_Fields | Invalid_Email_Data_One_Max_Char                        | Field_Error_Chief_Email         |
 
-
   @rsp-1863 @saveLaterSponsorEmailValidations
   Scenario Outline: Validate error messages when user saves the project with invalid sponsor email data on key project roles page
     And I click the 'Create_Project_Record' button on the 'My_Research_Projects_Page'
@@ -543,7 +540,7 @@ Feature: Create Amendment - Create Project
     And I can see the key project roles page
     Then I fill the key project roles page with '<Key_Project_Roles>'
     And I capture the page screenshot
-    And  I click the 'Save_For_Later' button on the 'Key_Project_Roles_Page'
+    And I click the 'Save_For_Later' button on the 'Key_Project_Roles_Page'
     Then I validate '<Field_And_Summary_Error_Message>' displayed on 'Key_Project_Roles_Page'
     And I capture the page screenshot
 
@@ -574,3 +571,106 @@ Feature: Create Amendment - Create Project
       | Valid_Data_All_Fields | Invalid_Email_Data_Two_Reserved_Domain                 | Field_Error_Sponsor_Email       |
       | Valid_Data_All_Fields | Invalid_Email_Data_Two_Punycode                        | Field_Error_Sponsor_Email       |
       | Valid_Data_All_Fields | Invalid_Email_Data_Two_Max_Char                        | Field_Error_Sponsor_Email       |
+
+  @rsp-1861 @rsp-3670 @jsEnabled
+  Scenario Outline: Validate user is able to fill sponsor organisation in key project roles page with valid data
+    And I click the '<Navigation_Button_First>' button on the 'My_Research_Projects_Page'
+    And I click the '<Navigation_Button_Second>' button on the 'Create_Project_Record_Page'
+    And I fill the unique iras id in project details iras page
+    And I click the '<Navigation_Button_Third>' button on the 'Project_Details_IRAS_Page'
+    And I fill the project details title page with '<Project_Details_Title>'
+    When I click the '<Navigation_Button_Third>' button on the 'Project_Details_Title_Page'
+    Then I can see the key project roles page
+    And I capture the page screenshot
+    Then I can see the '<Validation_Text>' ui labels on the key project roles page
+    Then I fill the key project roles page with '<Key_Project_Roles>'
+    And I capture the page screenshot
+    Then I click the '<Navigation_Button_Third>' button on the 'Key_Project_Roles_Page'
+    Then I can see the research locations page
+    When I click the '<Navigation_Link>' link on the 'Research_Locations_Page'
+    Then I can see the key project roles page
+    Then I can see previously saved values for '<Key_Project_Roles>' displayed on the key project roles page
+    And I capture the page screenshot
+    Then I click the '<Navigation_Button_Third>' button on the 'Research_Locations_Page'
+    Then I fill the research locations page with '<Research_Locations>'
+    When I click the '<Navigation_Button_Third>' button on the 'Research_Locations_Page'
+    Then I can see the review your answers page
+    And I capture the page screenshot
+    Then I can validate the field values of '<Project_Details_Title>' page '<Key_Project_Roles>' page and '<Research_Locations>' page
+    And I click the change link '<Change_Link_Field>' on review your answers page
+    Then I can see the key project roles page
+    Then I can see previously saved values for '<Key_Project_Roles>' displayed on the key project roles page
+    And I capture the page screenshot
+    And I fill the key project roles page with '<Key_Project_Roles_Change>'
+    And I capture the page screenshot
+    When I click the 'Save_Changes' button on the 'Key_Project_Roles_Page'
+    Then I can see the review your answers page
+    And I capture the page screenshot
+    Then I can validate the field values of '<Project_Details_Title>' page '<Key_Project_Roles_Change>' page and '<Research_Locations>' page
+    And I click the change link '<Change_Link_Field>' on review your answers page
+    Then I can see the key project roles page
+    Then I can see previously saved values for '<Key_Project_Roles_Change>' displayed on the key project roles page
+    And I capture the page screenshot
+    And I fill the key project roles page with '<Key_Project_Roles_Change_Blank>'
+    And I capture the page screenshot
+    When I click the 'Save_Changes' button on the 'Key_Project_Roles_Page'
+    Then I can see the review your answers page
+    And I capture the page screenshot
+    Then I can validate the field values of '<Project_Details_Title>' page '<Key_Project_Roles_Change_Blank>' page and '<Research_Locations>' page
+    And I click the enter link '<Enter_Link_Field>' on review your answers page
+    Then I can see the key project roles page
+    Then I can see previously saved values for '<Key_Project_Roles_Change_Blank>' displayed on the key project roles page
+    And I capture the page screenshot
+
+    Examples:
+      | Navigation_Button_First | Navigation_Button_Second | Navigation_Button_Third | Validation_Text | Project_Details_Title | Key_Project_Roles     | Key_Project_Roles_Change               | Key_Project_Roles_Change_Blank  | Research_Locations    | Change_Link_Field            | Enter_Link_Field             | Navigation_Link |
+      | Create_Project_Record   | Start                    | Save_Continue           | Label_Texts     | Valid_Data_All_Fields | Valid_Data_All_Fields | Sponsor_Organisation_Full_Text_Aalborg | Sponsor_Organisation_Text_Blank | Valid_Data_All_Fields | primary_sponsor_organisation | primary_sponsor_organisation | Back            |
+      | Create_Project_Record   | Start                    | Save_Continue           | Label_Texts     | Valid_Data_All_Fields | Valid_Data_All_Fields | Sponsor_Organisation_Text_Brackets     | Sponsor_Organisation_Text_Blank | Valid_Data_All_Fields | primary_sponsor_organisation | primary_sponsor_organisation | Back            |
+      | Create_Project_Record   | Start                    | Save_Continue           | Label_Texts     | Valid_Data_All_Fields | Valid_Data_All_Fields | Sponsor_Organisation_Text_Amp          | Sponsor_Organisation_Text_Blank | Valid_Data_All_Fields | primary_sponsor_organisation | primary_sponsor_organisation | Back            |
+      | Create_Project_Record   | Start                    | Save_Continue           | Label_Texts     | Valid_Data_All_Fields | Valid_Data_All_Fields | Sponsor_Organisation_Text_Dot_Comma    | Sponsor_Organisation_Text_Blank | Valid_Data_All_Fields | primary_sponsor_organisation | primary_sponsor_organisation | Back            |
+      | Create_Project_Record   | Start                    | Save_Continue           | Label_Texts     | Valid_Data_All_Fields | Valid_Data_All_Fields | Sponsor_Organisation_Text_Slash        | Sponsor_Organisation_Text_Blank | Valid_Data_All_Fields | primary_sponsor_organisation | primary_sponsor_organisation | Back            |
+      | Create_Project_Record   | Start                    | Save_Continue           | Label_Texts     | Valid_Data_All_Fields | Valid_Data_All_Fields | Sponsor_Organisation_Text_Hyphen       | Sponsor_Organisation_Text_Blank | Valid_Data_All_Fields | primary_sponsor_organisation | primary_sponsor_organisation | Back            |
+
+  @rsp-1861 @rsp-3670 @jsEnabled
+  Scenario Outline: Validate the primary sponsor organisation suggestion list in key project roles page
+    And I click the '<Navigation_Button_First>' button on the 'My_Research_Projects_Page'
+    And I click the '<Navigation_Button_Second>' button on the 'Create_Project_Record_Page'
+    And I fill the unique iras id in project details iras page
+    And I click the '<Navigation_Button_Third>' button on the 'Project_Details_IRAS_Page'
+    And I fill the project details title page with '<Project_Details_Title>'
+    When I click the '<Navigation_Button_Third>' button on the 'Project_Details_Title_Page'
+    Then I can see the key project roles page
+    And I capture the page screenshot
+    When I authorise the rts api using '<RTS_API_Data>'
+    Then I make a request to the rts api using '<RTS_Request>' dataset for sponsor organisation
+    And I type valid '<Sponsor_Organisation>' for primary sponsor organisation suggestion box and validate the suggestion list along with '<Suggestion_List_Headers>'
+    And I type invalid '<Sponsor_Organisation_Invalid>' for primary sponsor organisation suggestion box and validate the suggestion list along with '<Suggestion_List_Headers>'
+    And I type min characters '<Sponsor_Organisation_Min>' for primary sponsor organisation suggestion box and validate the suggestion list along with '<Suggestion_List_Headers>'
+    And I capture the page screenshot
+
+    Examples:
+      | Navigation_Button_First | Navigation_Button_Second | Navigation_Button_Third | Project_Details_Title | Sponsor_Organisation                          | Sponsor_Organisation_Invalid      | Sponsor_Organisation_Min      | Suggestion_List_Headers        | RTS_API_Data         | RTS_Request                                 |
+      | Create_Project_Record   | Start                    | Save_Continue           | Valid_Data_All_Fields | Sponsor_Organisation_Partial_Text_NHS         | Sponsor_Organisation_Invalid_Data | Sponsor_Organisation_Min_Char | Suggestion_List_Common_Headers | RTS_NIHR_FHIR_Config | RTS_Active_Sponsor_Organisation_NHS         |
+      | Create_Project_Record   | Start                    | Save_Continue           | Valid_Data_All_Fields | Sponsor_Organisation_Text_Partial_Brackets    | Sponsor_Organisation_Invalid_Data | Sponsor_Organisation_Min_Char | Suggestion_List_Common_Headers | RTS_NIHR_FHIR_Config | RTS_Active_Sponsor_Organisation_Brackets    |
+      | Create_Project_Record   | Start                    | Save_Continue           | Valid_Data_All_Fields | Sponsor_Organisation_Text_Partial_Dot_Comma   | Sponsor_Organisation_Invalid_Data | Sponsor_Organisation_Min_Char | Suggestion_List_Common_Headers | RTS_NIHR_FHIR_Config | RTS_Active_Sponsor_Organisation_Dot_Comma   |
+      | Create_Project_Record   | Start                    | Save_Continue           | Valid_Data_All_Fields | Sponsor_Organisation_Text_Partial_Slash       | Sponsor_Organisation_Invalid_Data | Sponsor_Organisation_Min_Char | Suggestion_List_Common_Headers | RTS_NIHR_FHIR_Config | RTS_Active_Sponsor_Organisation_Slash       |
+      | Create_Project_Record   | Start                    | Save_Continue           | Valid_Data_All_Fields | Sponsor_Organisation_Text_Partial_Hyphen      | Sponsor_Organisation_Invalid_Data | Sponsor_Organisation_Min_Char | Suggestion_List_Common_Headers | RTS_NIHR_FHIR_Config | RTS_Active_Sponsor_Organisation_Hyphen      |
+      | Create_Project_Record   | Start                    | Save_Continue           | Valid_Data_All_Fields | Sponsor_Organisation_Text_Partial_Start_Space | Sponsor_Organisation_Invalid_Data | Sponsor_Organisation_Min_Char | Suggestion_List_Common_Headers | RTS_NIHR_FHIR_Config | RTS_Active_Sponsor_Organisation_Start_Space |
+      | Create_Project_Record   | Start                    | Save_Continue           | Valid_Data_All_Fields | Sponsor_Organisation_Text_Partial_End_Space   | Sponsor_Organisation_Invalid_Data | Sponsor_Organisation_Min_Char | Suggestion_List_Common_Headers | RTS_NIHR_FHIR_Config | RTS_Active_Sponsor_Organisation_Ends_Space  |
+
+  @rsp-1861 @jsEnabled
+  Scenario Outline: Validate the active primary sponsor organisation from rts with data in database
+    When I authorise the rts api using '<RTS_API_Data>'
+    Then I make a request to the rts api using '<RTS_Request>' dataset for sponsor organisation
+    And I validate the list of sponsor organisations retrieved in ui compared to the rts response received using '<RTS_Request>'
+
+    Examples:
+      | RTS_API_Data         | RTS_Request                                 |
+      | RTS_NIHR_FHIR_Config | RTS_Active_Sponsor_Organisation_NHS         |
+      | RTS_NIHR_FHIR_Config | RTS_Active_Sponsor_Organisation_MAN         |
+      | RTS_NIHR_FHIR_Config | RTS_Active_Sponsor_Organisation_Brackets    |
+      | RTS_NIHR_FHIR_Config | RTS_Active_Sponsor_Organisation_Dot_Comma   |
+      | RTS_NIHR_FHIR_Config | RTS_Active_Sponsor_Organisation_Slash       |
+      | RTS_NIHR_FHIR_Config | RTS_Active_Sponsor_Organisation_Hyphen      |
+      | RTS_NIHR_FHIR_Config | RTS_Active_Sponsor_Organisation_Start_Space |
+      | RTS_NIHR_FHIR_Config | RTS_Active_Sponsor_Organisation_Ends_Space  |


Reviews:
user: login: Chris-McNeill-PA-HRA
body: Very good work, just a few comments on minor issues that need addressed, then can approve
state: CHANGES_REQUESTED
author_association: COLLABORATOR
submitted_at: 2025-05-22T10:04:18Z
user: login: alfreddcruz-HRA
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-23T08:45:13Z
user: login: alfreddcruz-HRA
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-23T08:47:37Z
user: login: alfreddcruz-HRA
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-23T08:53:38Z
user: login: alfreddcruz-HRA
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-23T09:17:37Z
user: login: alfreddcruz-HRA
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-23T09:49:29Z
user: login: Chris-McNeill-PA-HRA
body: All good after recent updated
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-05-23T13:15:27Z

Review comments:
diff_hunk: @@ -24,22 +27,21 @@ export default class KeyProjectRolesPage {
     //Locators
     this.pageHeading = this.page.getByTestId('title');
     this.chief_investigator_header_label = this.page.locator('label[for="IQA0311_Text"]');
-    this.chief_investigator_email_label = this.page
-      .locator('label[for="IQA0311_Text"]')
-      .locator('..')
-      .locator('..')
-      .locator('div[id="rule-hint"]');
+    this.chief_investigator_email_label = this.page.locator('div[id="chief-investigator-hint"]');
path: src/pages/IRAS/makeChanges/KeyProjectRolesPage.ts
user: login: Chris-McNeill-PA-HRA
body: For this, `sponsor_contact_email_label` and `primary_sponsor_organisation_jsenabled_text` please use the page.getByTestId() method
created_at: 2025-05-22T08:57:30Z
author_association: COLLABORATOR
diff_hunk: @@ -24,22 +27,21 @@ export default class KeyProjectRolesPage {
     //Locators
     this.pageHeading = this.page.getByTestId('title');
     this.chief_investigator_header_label = this.page.locator('label[for="IQA0311_Text"]');
-    this.chief_investigator_email_label = this.page
-      .locator('label[for="IQA0311_Text"]')
-      .locator('..')
-      .locator('..')
-      .locator('div[id="rule-hint"]');
+    this.chief_investigator_email_label = this.page.locator('div[id="chief-investigator-hint"]');
     this.sponsor_contact_header_label = this.page.locator('label[for="IQA0313_Text"]');
-    this.sponsor_contact_email_label = this.page
-      .locator('label[for="IQA0313_Text"]')
-      .locator('..')
-      .locator('..')
-      .locator('div[id="rule-hint"]');
+    this.sponsor_contact_email_label = this.page.locator('div[id="sponsor-contact-hint"]');
     this.chief_investigator_email_text = this.page.getByTestId('IQA0311_Text');
     this.sponsor_contact_email_text = this.page.getByTestId('IQA0313_Text');
     this.chief_investigator_email_text_summary_error_label = this.page.locator('a[href="#Questions[0].AnswerText"]');
     this.sponsor_contact_email_text_summary_error_label = this.page.locator('a[href="#Questions[1].AnswerText"]');
     this.primary_sponsor_organisation_text = this.page.getByTestId('IQA0312_Text');
+    this.primary_sponsor_organisation_header_label = this.page.locator('label[for="IQA0312_Text"]');
+    this.primary_sponsor_organisation_jsenabled_text = this.page.locator(
+      'div[id="Questions[1].AnswerText"] input[id="input-autocomplete"]'
+    );
+    this.primary_sponsor_organisation_suggestion_list_labels = this.page.locator(
path: src/pages/IRAS/makeChanges/KeyProjectRolesPage.ts
user: login: Chris-McNeill-PA-HRA
body: Can combine the getByTestId and getByRole methods here.
Roles available include list, listbox and listitem, which should work for this
created_at: 2025-05-22T08:59:09Z
author_association: COLLABORATOR
diff_hunk: @@ -219,3 +219,20 @@ Feature: Create Amendment - Create Project - Regression Tests
     Examples:
       | Navigation_Button_First | Navigation_Button_Second | Project_Details_IRAS | Navigation_Button_Third | Validation_Text | Project_Details_Title | Key_Project_Roles     | Research_Locations   |
       | Create_Project_Record   | Start                    | Valid_IRAS_ID_Min    | Save_Continue           | Label_Texts     | Valid_Data_All_Fields | Valid_Data_All_Fields | Data_With_No_NHS_HSC |
+
+  @CreateProjectRTSRegression @jsEnabled
+  Scenario Outline: Validate the active primary sponsor organisation from rts with data in database
+    When I authorise the rts api using '<RTS_API_Data>' and store the bearer token in memory
path: tests/features/cross-compatible/stories/regressionTests/CreateProject.feature
user: login: Chris-McNeill-PA-HRA
body: For this step and the request step remove the reference to memory, 
So just `I authorise the rts api using '<RTS_API_Data>'` & `I make a request to the rts api using '<RTS_Request>' dataset for sponsor organisation`.
Steps should only talk about what your doing  on the screen and not whats happening in the background.
created_at: 2025-05-22T10:01:18Z
author_association: COLLABORATOR
diff_hunk: @@ -219,3 +219,20 @@ Feature: Create Amendment - Create Project - Regression Tests
     Examples:
       | Navigation_Button_First | Navigation_Button_Second | Project_Details_IRAS | Navigation_Button_Third | Validation_Text | Project_Details_Title | Key_Project_Roles     | Research_Locations   |
       | Create_Project_Record   | Start                    | Valid_IRAS_ID_Min    | Save_Continue           | Label_Texts     | Valid_Data_All_Fields | Valid_Data_All_Fields | Data_With_No_NHS_HSC |
+
+  @CreateProjectRTSRegression @jsEnabled
+  Scenario Outline: Validate the active primary sponsor organisation from rts with data in database
+    When I authorise the rts api using '<RTS_API_Data>' and store the bearer token in memory
+    Then I make a request to the rts api using '<RTS_Request>' dataset for sponsor organisation and save the response in memory
+    And I validate the list of sponsor organisations retrieved in ui vs rts response recieved using '<RTS_Request>'
path: tests/features/cross-compatible/stories/regressionTests/CreateProject.feature
user: login: Chris-McNeill-PA-HRA
body: Since its sandwiched between 2 acronyms and would change `vs` to versus
OR `I validate the list of sponsor organisations retrieved in ui compared to the rts response received using '<RTS_Request>'`
Also `recieved` is the correct spelling 
created_at: 2025-05-22T10:03:31Z
author_association: COLLABORATOR
diff_hunk: @@ -24,22 +27,21 @@ export default class KeyProjectRolesPage {
     //Locators
     this.pageHeading = this.page.getByTestId('title');
     this.chief_investigator_header_label = this.page.locator('label[for="IQA0311_Text"]');
-    this.chief_investigator_email_label = this.page
-      .locator('label[for="IQA0311_Text"]')
-      .locator('..')
-      .locator('..')
-      .locator('div[id="rule-hint"]');
+    this.chief_investigator_email_label = this.page.locator('div[id="chief-investigator-hint"]');
path: src/pages/IRAS/makeChanges/KeyProjectRolesPage.ts
user: login: alfreddcruz-HRA
body: Updated as per the comment
created_at: 2025-05-23T08:45:13Z
author_association: COLLABORATOR
diff_hunk: @@ -24,22 +27,21 @@ export default class KeyProjectRolesPage {
     //Locators
     this.pageHeading = this.page.getByTestId('title');
     this.chief_investigator_header_label = this.page.locator('label[for="IQA0311_Text"]');
-    this.chief_investigator_email_label = this.page
-      .locator('label[for="IQA0311_Text"]')
-      .locator('..')
-      .locator('..')
-      .locator('div[id="rule-hint"]');
+    this.chief_investigator_email_label = this.page.locator('div[id="chief-investigator-hint"]');
     this.sponsor_contact_header_label = this.page.locator('label[for="IQA0313_Text"]');
-    this.sponsor_contact_email_label = this.page
-      .locator('label[for="IQA0313_Text"]')
-      .locator('..')
-      .locator('..')
-      .locator('div[id="rule-hint"]');
+    this.sponsor_contact_email_label = this.page.locator('div[id="sponsor-contact-hint"]');
     this.chief_investigator_email_text = this.page.getByTestId('IQA0311_Text');
     this.sponsor_contact_email_text = this.page.getByTestId('IQA0313_Text');
     this.chief_investigator_email_text_summary_error_label = this.page.locator('a[href="#Questions[0].AnswerText"]');
     this.sponsor_contact_email_text_summary_error_label = this.page.locator('a[href="#Questions[1].AnswerText"]');
     this.primary_sponsor_organisation_text = this.page.getByTestId('IQA0312_Text');
+    this.primary_sponsor_organisation_header_label = this.page.locator('label[for="IQA0312_Text"]');
+    this.primary_sponsor_organisation_jsenabled_text = this.page.locator(
+      'div[id="Questions[1].AnswerText"] input[id="input-autocomplete"]'
+    );
+    this.primary_sponsor_organisation_suggestion_list_labels = this.page.locator(
path: src/pages/IRAS/makeChanges/KeyProjectRolesPage.ts
user: login: alfreddcruz-HRA
body: Tried doing this. Currently changed this to: this.page.getByTestId('Questions[1].AnswerText').locator('ul[role="listbox"] li');
I did try below locators as well, but when debugging scripts are failing:
1. this.page.getByTestId('Questions[1].AnswerText').getByRole('listitem');
2. this.page.getByTestId('Questions[1].AnswerText').getByRole('listbox');
3. this.page.getByTestId('Questions[1].AnswerText').getByRole('listbox').getByRole('listitem');
4. this.page.getByTestId('Questions[1].AnswerText').getByRole('listbox').locator('li');
5. this.page.getByTestId('Questions[1].AnswerText').getByRole('listbox').getByRole('list');
6. this.page.getByTestId('Questions[1].AnswerText').getByRole('list');
created_at: 2025-05-23T08:47:37Z
author_association: COLLABORATOR
diff_hunk: @@ -219,3 +219,20 @@ Feature: Create Amendment - Create Project - Regression Tests
     Examples:
       | Navigation_Button_First | Navigation_Button_Second | Project_Details_IRAS | Navigation_Button_Third | Validation_Text | Project_Details_Title | Key_Project_Roles     | Research_Locations   |
       | Create_Project_Record   | Start                    | Valid_IRAS_ID_Min    | Save_Continue           | Label_Texts     | Valid_Data_All_Fields | Valid_Data_All_Fields | Data_With_No_NHS_HSC |
+
+  @CreateProjectRTSRegression @jsEnabled
+  Scenario Outline: Validate the active primary sponsor organisation from rts with data in database
+    When I authorise the rts api using '<RTS_API_Data>' and store the bearer token in memory
path: tests/features/cross-compatible/stories/regressionTests/CreateProject.feature
user: login: alfreddcruz-HRA
body: Updated as per comment
created_at: 2025-05-23T08:53:38Z
author_association: COLLABORATOR
diff_hunk: @@ -219,3 +219,20 @@ Feature: Create Amendment - Create Project - Regression Tests
     Examples:
       | Navigation_Button_First | Navigation_Button_Second | Project_Details_IRAS | Navigation_Button_Third | Validation_Text | Project_Details_Title | Key_Project_Roles     | Research_Locations   |
       | Create_Project_Record   | Start                    | Valid_IRAS_ID_Min    | Save_Continue           | Label_Texts     | Valid_Data_All_Fields | Valid_Data_All_Fields | Data_With_No_NHS_HSC |
+
+  @CreateProjectRTSRegression @jsEnabled
+  Scenario Outline: Validate the active primary sponsor organisation from rts with data in database
+    When I authorise the rts api using '<RTS_API_Data>' and store the bearer token in memory
+    Then I make a request to the rts api using '<RTS_Request>' dataset for sponsor organisation and save the response in memory
+    And I validate the list of sponsor organisations retrieved in ui vs rts response recieved using '<RTS_Request>'
path: tests/features/cross-compatible/stories/regressionTests/CreateProject.feature
user: login: alfreddcruz-HRA
body: Updated as per comment
created_at: 2025-05-23T09:17:37Z
author_association: COLLABORATOR
diff_hunk: @@ -24,22 +27,21 @@ export default class KeyProjectRolesPage {
     //Locators
     this.pageHeading = this.page.getByTestId('title');
     this.chief_investigator_header_label = this.page.locator('label[for="IQA0311_Text"]');
-    this.chief_investigator_email_label = this.page
-      .locator('label[for="IQA0311_Text"]')
-      .locator('..')
-      .locator('..')
-      .locator('div[id="rule-hint"]');
+    this.chief_investigator_email_label = this.page.locator('div[id="chief-investigator-hint"]');
     this.sponsor_contact_header_label = this.page.locator('label[for="IQA0313_Text"]');
-    this.sponsor_contact_email_label = this.page
-      .locator('label[for="IQA0313_Text"]')
-      .locator('..')
-      .locator('..')
-      .locator('div[id="rule-hint"]');
+    this.sponsor_contact_email_label = this.page.locator('div[id="sponsor-contact-hint"]');
     this.chief_investigator_email_text = this.page.getByTestId('IQA0311_Text');
     this.sponsor_contact_email_text = this.page.getByTestId('IQA0313_Text');
     this.chief_investigator_email_text_summary_error_label = this.page.locator('a[href="#Questions[0].AnswerText"]');
     this.sponsor_contact_email_text_summary_error_label = this.page.locator('a[href="#Questions[1].AnswerText"]');
     this.primary_sponsor_organisation_text = this.page.getByTestId('IQA0312_Text');
+    this.primary_sponsor_organisation_header_label = this.page.locator('label[for="IQA0312_Text"]');
+    this.primary_sponsor_organisation_jsenabled_text = this.page.locator(
+      'div[id="Questions[1].AnswerText"] input[id="input-autocomplete"]'
+    );
+    this.primary_sponsor_organisation_suggestion_list_labels = this.page.locator(
path: src/pages/IRAS/makeChanges/KeyProjectRolesPage.ts
user: login: alfreddcruz-HRA
body: Please ignore above comment. Thanks to @Tiji-rsp-hra , Have updated the locator:
this.primary_sponsor_organisation_suggestion_list_labels = this.page
      .getByRole('combobox', { name: 'Primary sponsor organisation' })
      .locator('..')
      .getByRole('option');
created_at: 2025-05-23T09:49:29Z
author_association: COLLABORATOR

PR comments:
user: login: sonarqubecloud[bot]
created_at: 2025-05-23T10:56:54Z
body: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=HealthResearchAuthority_rsp-iras-qa&pullRequest=35) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 New issues](https://sonarcloud.io/project/issues?id=HealthResearchAuthority_rsp-iras-qa&pullRequest=35&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=HealthResearchAuthority_rsp-iras-qa&pullRequest=35&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=HealthResearchAuthority_rsp-iras-qa&pullRequest=35&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=HealthResearchAuthority_rsp-iras-qa&pullRequest=35&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=HealthResearchAuthority_rsp-iras-qa&pullRequest=35&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=HealthResearchAuthority_rsp-iras-qa&pullRequest=35)


author_association: NONE