diff --git a/galasa-ui/messages/de.json b/galasa-ui/messages/de.json
index c7ef3759..2d1c0ce4 100644
--- a/galasa-ui/messages/de.json
+++ b/galasa-ui/messages/de.json
@@ -249,6 +249,7 @@
"group": "Gruppe",
"submissionId": "Übermittlungs-ID",
"requestor": "Anforderer",
+ "user": "Benutzer",
"submitted": "Eingereicht",
"started": "Gestartet",
"finished": "Beendet",
@@ -325,6 +326,7 @@
"submittedAt": "Eingereicht am",
"runName": "Name des Testlaufs",
"requestor": "Anforderer",
+ "user": "Benutzer",
"group": "Gruppe",
"bundle": "Bundle",
"package": "Paket",
@@ -358,6 +360,7 @@
"submittedAt": "Eingereicht am",
"runName": "Ausführungsname",
"requestor": "Anforderer",
+ "user": "Benutzer",
"submissionId": "Einreichungs-ID",
"group": "Gruppe",
"bundle": "Paket",
@@ -445,6 +448,11 @@
"requestor": {
"label": "Anforderer",
"placeholder": "beliebig",
+ "description": "Geben Sie den Namen des Anforderers ein, dessen Token zum Anfordern der Testläufe verwendet wurde, die Sie finden möchten."
+ },
+ "user": {
+ "label": "Benutzer",
+ "placeholder": "beliebig",
"description": "Geben Sie den Namen des Benutzers ein, der die Testläufe angefordert hat, die Sie finden möchten."
},
"group": {
@@ -517,6 +525,7 @@
"submittedAt": "Eingereicht am",
"runName": "Name des Testlaufs",
"requestor": "Anforderer",
+ "user": "Benutzer",
"group": "Gruppe",
"bundle": "Bundle",
"package": "Paket",
diff --git a/galasa-ui/messages/en.json b/galasa-ui/messages/en.json
index 1aacedc6..e9c30104 100644
--- a/galasa-ui/messages/en.json
+++ b/galasa-ui/messages/en.json
@@ -228,6 +228,7 @@
"group": "Group",
"submissionId": "Submission ID",
"requestor": "Requestor",
+ "user": "User",
"submitted": "Submitted",
"started": "Started",
"finished": "Finished",
@@ -304,6 +305,7 @@
"submittedAt": "Submitted at",
"runName": "Test Run Name",
"requestor": "Requestor",
+ "user": "User",
"group": "Group",
"bundle": "Bundle",
"package": "Package",
@@ -337,6 +339,7 @@
"submittedAt": "Submitted At",
"runName": "Run Name",
"requestor": "Requestor",
+ "user": "User",
"submissionId": "Submission ID",
"group": "Group",
"bundle": "Bundle",
@@ -423,6 +426,11 @@
"requestor": {
"label": "Requestor",
"placeholder": "any",
+ "description": "Enter the name of the requestor whose token was used to request the test runs you want to find."
+ },
+ "user": {
+ "label": "User",
+ "placeholder": "any",
"description": "Enter the name of the user who requested the test runs you want to find."
},
"group": {
@@ -495,6 +503,7 @@
"submittedAt": "Submitted at",
"runName": "Test Run Name",
"requestor": "Requestor",
+ "user": "User",
"group": "Group",
"bundle": "Bundle",
"package": "Package",
diff --git a/galasa-ui/src/app/internal-api/test-runs/route.ts b/galasa-ui/src/app/internal-api/test-runs/route.ts
index c5aea868..ad745c90 100644
--- a/galasa-ui/src/app/internal-api/test-runs/route.ts
+++ b/galasa-ui/src/app/internal-api/test-runs/route.ts
@@ -38,6 +38,7 @@ export async function GET(request: NextRequest) {
toDate,
runName: searchParams.get(TEST_RUNS_QUERY_PARAMS.RUN_NAME) || undefined,
requestor: searchParams.get(TEST_RUNS_QUERY_PARAMS.REQUESTOR) || undefined,
+ user: searchParams.get(TEST_RUNS_QUERY_PARAMS.USER) || undefined,
group: searchParams.get(TEST_RUNS_QUERY_PARAMS.GROUP) || undefined,
submissionId: searchParams.get(TEST_RUNS_QUERY_PARAMS.SUBMISSION_ID) || undefined,
bundle: searchParams.get(TEST_RUNS_QUERY_PARAMS.BUNDLE) || undefined,
diff --git a/galasa-ui/src/components/test-runs/TestRunsTabs.tsx b/galasa-ui/src/components/test-runs/TestRunsTabs.tsx
index 9fdb0ebc..b6006790 100644
--- a/galasa-ui/src/components/test-runs/TestRunsTabs.tsx
+++ b/galasa-ui/src/components/test-runs/TestRunsTabs.tsx
@@ -94,6 +94,7 @@ export default function TestRunsTabs({
submittedAt: structure.queued || 'N/A',
runName: structure.runName || 'N/A',
requestor: structure.requestor || 'N/A',
+ user: structure.user || 'N/A',
group: structure.group || 'N/A',
bundle: structure.bundle || 'N/A',
package: structure.testName?.substring(0, structure.testName.lastIndexOf('.')) || 'N/A',
@@ -121,6 +122,7 @@ export default function TestRunsTabs({
TEST_RUNS_QUERY_PARAMS.DURATION,
TEST_RUNS_QUERY_PARAMS.RUN_NAME,
TEST_RUNS_QUERY_PARAMS.REQUESTOR,
+ TEST_RUNS_QUERY_PARAMS.USER,
TEST_RUNS_QUERY_PARAMS.GROUP,
TEST_RUNS_QUERY_PARAMS.SUBMISSION_ID,
TEST_RUNS_QUERY_PARAMS.BUNDLE,
@@ -141,7 +143,8 @@ export default function TestRunsTabs({
key === TEST_RUNS_QUERY_PARAMS.TAGS ||
key === TEST_RUNS_QUERY_PARAMS.RESULT ||
key === TEST_RUNS_QUERY_PARAMS.STATUS ||
- key === TEST_RUNS_QUERY_PARAMS.REQUESTOR
+ key === TEST_RUNS_QUERY_PARAMS.REQUESTOR ||
+ key === TEST_RUNS_QUERY_PARAMS.USER
) {
value = value?.split(',').sort().join(',');
}
diff --git a/galasa-ui/src/components/test-runs/search-criteria/SearchCriteriaContent.tsx b/galasa-ui/src/components/test-runs/search-criteria/SearchCriteriaContent.tsx
index e69badd8..2ebe1995 100644
--- a/galasa-ui/src/components/test-runs/search-criteria/SearchCriteriaContent.tsx
+++ b/galasa-ui/src/components/test-runs/search-criteria/SearchCriteriaContent.tsx
@@ -55,6 +55,12 @@ export default function SearchCriteriaContent({
placeHolder: 'any',
description: translations('fields.requestor.description'),
},
+ {
+ id: TEST_RUNS_QUERY_PARAMS.USER,
+ label: translations('fields.user.label'),
+ placeHolder: 'any',
+ description: translations('fields.user.description'),
+ },
{
id: TEST_RUNS_QUERY_PARAMS.GROUP,
label: translations('fields.group.label'),
@@ -298,6 +304,9 @@ export default function SearchCriteriaContent({
case TEST_RUNS_QUERY_PARAMS.REQUESTOR:
customComponent = ;
break;
+ case TEST_RUNS_QUERY_PARAMS.USER:
+ customComponent = ;
+ break;
case TEST_RUNS_QUERY_PARAMS.RESULT:
case TEST_RUNS_QUERY_PARAMS.STATUS:
customComponent = ;
diff --git a/galasa-ui/src/components/test-runs/test-run-details/OverviewTab.tsx b/galasa-ui/src/components/test-runs/test-run-details/OverviewTab.tsx
index a5bc6dd0..2c3ff4d9 100644
--- a/galasa-ui/src/components/test-runs/test-run-details/OverviewTab.tsx
+++ b/galasa-ui/src/components/test-runs/test-run-details/OverviewTab.tsx
@@ -55,6 +55,7 @@ const OverviewTab = ({ metadata }: { metadata: RunMetadata }) => {
+
diff --git a/galasa-ui/src/components/test-runs/test-run-details/TestRunDetails.tsx b/galasa-ui/src/components/test-runs/test-run-details/TestRunDetails.tsx
index f7d4d1d8..d2c03b16 100644
--- a/galasa-ui/src/components/test-runs/test-run-details/TestRunDetails.tsx
+++ b/galasa-ui/src/components/test-runs/test-run-details/TestRunDetails.tsx
@@ -130,6 +130,7 @@ const TestRunDetails = ({
runDetails.testStructure?.testName.lastIndexOf('.')
) || 'N/A',
requestor: runDetails.testStructure?.requestor!,
+ user: runDetails.testStructure?.user!,
rawSubmittedAt: runDetails.testStructure?.queued,
submitted: runDetails.testStructure?.queued
? formatDate(new Date(runDetails.testStructure?.queued!))
diff --git a/galasa-ui/src/tests/components/test-runs/TestRunsTabs.test.tsx b/galasa-ui/src/tests/components/test-runs/TestRunsTabs.test.tsx
index 8964f1c0..1a38663b 100644
--- a/galasa-ui/src/tests/components/test-runs/TestRunsTabs.test.tsx
+++ b/galasa-ui/src/tests/components/test-runs/TestRunsTabs.test.tsx
@@ -142,6 +142,7 @@ jest.mock('@/utils/constants/common', () => ({
TO: 'to',
RUN_NAME: 'runName',
REQUESTOR: 'requestor',
+ USER: 'user',
GROUP: 'group',
SUBMISSION_ID: 'submissionId',
BUNDLE: 'bundle',
@@ -160,6 +161,7 @@ jest.mock('@/utils/constants/common', () => ({
SEARCH_CRITERIA_KEYS: [
'runName',
'requestor',
+ 'user',
'group',
'submissionId',
'bundle',
@@ -418,7 +420,18 @@ describe('TestRunsTabs Component', () => {
// Act: Simulate a child component updating the state
const newOrder = [
{ id: 'result', columnName: 'Result' },
+ { id: 'tags', columnName: 'Tags' },
{ id: 'status', columnName: 'Status' },
+ { id: 'testName', columnName: 'Test Name (full)' },
+ { id: 'testShortName', columnName: 'Test Name (short)' },
+ { id: 'package', columnName: 'Package' },
+ { id: 'bundle', columnName: 'Bundle' },
+ { id: 'group', columnName: 'Group' },
+ { id: 'submissionId', columnName: 'Submission ID' },
+ { id: 'user', columnName: 'User' },
+ { id: 'requestor', columnName: 'Requestor' },
+ { id: 'runName', columnName: 'Test Run name' },
+ { id: 'submittedAt', columnName: 'Submitted at' },
];
act(() => {
if (capturedSetColumnsOrder) {
@@ -434,7 +447,9 @@ describe('TestRunsTabs Component', () => {
const decoded = decodeStateFromUrlParam(encodedQuery!);
const decodedParams = new URLSearchParams(decoded!);
- expect(decodedParams.get('columnsOrder')).toBe('result,status');
+ expect(decodedParams.get('columnsOrder')).toBe(
+ 'result,tags,status,testName,testShortName,package,bundle,group,submissionId,user,requestor,runName,submittedAt'
+ );
// Visible columns should be sorted with the same previous values
expect(decodedParams.get('visibleColumns')).toBe(
'requestor,result,runName,status,submittedAt,testName'
@@ -829,6 +844,7 @@ describe('TestRunsTabs Component', () => {
testName: 'N/A',
runName: 'N/A',
testShortName: 'N/A',
+ user: 'N/A',
};
beforeEach(() => {
diff --git a/galasa-ui/src/tests/components/test-runs/search-criteria/SearchCriteriaContent.test.tsx b/galasa-ui/src/tests/components/test-runs/search-criteria/SearchCriteriaContent.test.tsx
index c59967a8..8067f02b 100644
--- a/galasa-ui/src/tests/components/test-runs/search-criteria/SearchCriteriaContent.test.tsx
+++ b/galasa-ui/src/tests/components/test-runs/search-criteria/SearchCriteriaContent.test.tsx
@@ -70,6 +70,8 @@ jest.mock('next-intl', () => ({
'fields.runName.description': 'Description for Test Run Name',
'fields.requestor.label': 'Requestor',
'fields.requestor.description': 'Description for Requestor',
+ 'fields.user.label': 'User',
+ 'fields.user.description': 'Description for User',
'fields.group.label': 'Group',
'fields.group.description': 'Description for Group',
'fields.bundle.label': 'Bundle',
@@ -312,6 +314,15 @@ describe('SearchCriteriaContent', () => {
// The component should still render its structure
expect(screen.getByTestId('mock-custom-search-component')).toBeInTheDocument();
+
+ // Switch to another filter that depends on a promise
+ // The "User" field uses the requestorPromise as users and requestors are the same group of IDs
+ const userRow =
+ screen.getByText('User').closest('[role="row"]') || document.createElement('div');
+ fireEvent.click(userRow);
+
+ // The component should still render its structure
+ expect(screen.getByTestId('mock-custom-search-component')).toBeInTheDocument();
});
test('save button is disabled when state is not changed, and enabled when changed', async () => {
diff --git a/galasa-ui/src/tests/components/test-runs/test-run-details/OverviewTab.test.tsx b/galasa-ui/src/tests/components/test-runs/test-run-details/OverviewTab.test.tsx
index 8b7c223d..703cff07 100644
--- a/galasa-ui/src/tests/components/test-runs/test-run-details/OverviewTab.test.tsx
+++ b/galasa-ui/src/tests/components/test-runs/test-run-details/OverviewTab.test.tsx
@@ -43,6 +43,7 @@ jest.mock('next-intl', () => ({
group: 'Group',
submissionId: 'Submission ID',
requestor: 'Requestor',
+ user: 'User',
submitted: 'Submitted',
started: 'Started',
finished: 'Finished',
@@ -75,6 +76,7 @@ const completeMetadata: RunMetadata = {
package: 'com.example.tests',
submissionId: 'SUB123',
requestor: 'alice@example.com',
+ user: 'alice2@example.com',
submitted: '2025-06-10T09:00:00Z',
startedAt: '2025-06-10T09:05:00Z',
finishedAt: '2025-06-10T09:15:00Z',
@@ -98,6 +100,7 @@ describe('OverviewTab', () => {
['Group:', completeMetadata.group],
['Submission ID:', completeMetadata.submissionId],
['Requestor:', completeMetadata.requestor],
+ ['User:', completeMetadata.user],
].forEach(([label, value]) => {
// check the label
expect(screen.getByText(label as string, { selector: 'p' })).toBeInTheDocument();
diff --git a/galasa-ui/src/tests/components/test-runs/test-run-details/TestRunDetails.test.tsx b/galasa-ui/src/tests/components/test-runs/test-run-details/TestRunDetails.test.tsx
index 978de1e9..5c9fece7 100644
--- a/galasa-ui/src/tests/components/test-runs/test-run-details/TestRunDetails.test.tsx
+++ b/galasa-ui/src/tests/components/test-runs/test-run-details/TestRunDetails.test.tsx
@@ -280,6 +280,7 @@ describe('TestRunDetails', () => {
submissionId: 's1',
group: 'g1',
requestor: 'u1',
+ user: 'u1',
queued: '2025-01-01T00:00:00Z',
startTime: '2025-01-01T00:00:00Z',
endTime: '2025-01-01T01:00:00Z',
@@ -318,6 +319,7 @@ describe('TestRunDetails', () => {
submissionId: 'Sub123',
group: 'Grp',
requestor: 'User',
+ user: 'User',
queued: '2025-01-01T00:00:00Z',
startTime: '2025-01-01T00:00:00Z',
endTime: '2025-01-01T02:00:00Z',
@@ -388,6 +390,7 @@ describe('TestRunDetails', () => {
submissionId: '',
group: '',
requestor: '',
+ user: '',
queued: '',
startTime: '',
endTime: '',
@@ -432,6 +435,7 @@ describe('TestRunDetails', () => {
submissionId: 'Sub123',
group: 'Grp',
requestor: 'User',
+ user: 'User',
queued: '2025-01-01T00:00:00Z',
startTime: '2025-01-01T00:00:00Z',
endTime: '2025-01-01T02:00:00Z',
@@ -494,6 +498,7 @@ describe('TestRunDetails', () => {
submissionId: 'Submission',
group: 'Group',
requestor: 'Requestor',
+ user: 'Requestor',
queued: '2025-01-01T00:00:00Z',
startTime: '2025-01-01T00:00:00Z',
endTime: '2025-01-01T01:00:00Z',
@@ -554,6 +559,7 @@ describe('TestRunDetails', () => {
submissionId: 'Submission',
group: 'Group',
requestor: 'Requestor',
+ user: 'Requestor',
queued: '2025-01-01T00:00:00Z',
startTime: '2025-01-01T00:00:00Z',
endTime: '2025-01-01T01:00:00Z',
@@ -585,6 +591,7 @@ describe('TestRunDetails', () => {
submissionId: 'Submission',
group: 'Group',
requestor: 'Requestor',
+ user: 'Requestor',
queued: '2025-01-01T00:00:00Z',
startTime: '2025-01-01T00:00:00Z',
endTime: '2025-01-01T01:00:00Z',
diff --git a/galasa-ui/src/tests/contexts/TestRunsQueryParamsContext.test.tsx b/galasa-ui/src/tests/contexts/TestRunsQueryParamsContext.test.tsx
index c1f3541d..0507acd4 100644
--- a/galasa-ui/src/tests/contexts/TestRunsQueryParamsContext.test.tsx
+++ b/galasa-ui/src/tests/contexts/TestRunsQueryParamsContext.test.tsx
@@ -110,7 +110,25 @@ const TestComponent = () => {
Set Visible Columns
-