Skip to content

Commit

Permalink
[RHOAIENG-2985] Experiments - Run Integration
Browse files Browse the repository at this point in the history
  • Loading branch information
jpuzz0 committed Mar 19, 2024
1 parent 54cfc50 commit d7e0468
Show file tree
Hide file tree
Showing 56 changed files with 698 additions and 280 deletions.
108 changes: 75 additions & 33 deletions frontend/src/__tests__/cypress/cypress/e2e/pipelines/Experiments.cy.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
/* eslint-disable camelcase */
import { buildMockExperimentKF, buildMockRunKF } from '~/__mocks__';
import { mockDashboardConfig } from '~/__mocks__/mockDashboardConfig';
import { mockDataSciencePipelineApplicationK8sResource } from '~/__mocks__/mockDataSciencePipelinesApplicationK8sResource';
import { mockK8sResourceList } from '~/__mocks__/mockK8sResourceList';
import { buildMockPipelineV2, buildMockPipelines } from '~/__mocks__/mockPipelinesProxy';
import {
buildMockExperimentKF,
mockDashboardConfig,
mockDataSciencePipelineApplicationK8sResource,
mockK8sResourceList,
buildMockPipelineV2,
buildMockPipelines,
buildMockPipelineVersionV2,
buildMockPipelineVersionsV2,
} from '~/__mocks__/mockPipelineVersionsProxy';
import { mockProjectK8sResource } from '~/__mocks__/mockProjectK8sResource';
import { mockRouteK8sResource } from '~/__mocks__/mockRouteK8sResource';
import { mockStatus } from '~/__mocks__/mockStatus';
mockProjectK8sResource,
mockRouteK8sResource,
mockStatus,
} from '~/__mocks__';
import { experimentsTabs } from '~/__tests__/cypress/cypress/pages/pipelines/experiments';
import { RuntimeStateKF } from '~/concepts/pipelines/kfTypes';
import { verifyRelativeURL } from '~/__tests__/cypress/cypress/utils/url.cy';
import { pipelineRunsGlobal } from '~/__tests__/cypress/cypress/pages/pipelines';

const projectName = 'test-project-name';
const initialMockPipeline = buildMockPipelineV2({ display_name: 'Test pipeline' });
const initialMockPipelineVersion = buildMockPipelineVersionV2({
pipeline_id: initialMockPipeline.pipeline_id,
});
const mockExperimentArray = [
const mockExperiments = [
buildMockExperimentKF({
display_name: 'Test experiment 1',
experiment_id: '1',
Expand All @@ -34,24 +36,10 @@ const mockExperimentArray = [
}),
];

const runs = Array.from({ length: 5 }, (_, i) =>
buildMockRunKF({
display_name: 'Test triggered run 1',
run_id: `run-${i}`,
pipeline_version_reference: {
pipeline_id: initialMockPipeline.pipeline_id,
pipeline_version_id: initialMockPipelineVersion.pipeline_version_id,
},
experiment_id: '1',
created_at: '2024-02-01T00:00:00Z',
state: RuntimeStateKF.SUCCEEDED,
}),
);

describe('Pipeline Experiments', () => {
describe('Experiments', () => {
beforeEach(() => {
initIntercepts();
experimentsTabs.mockGetExperiments(mockExperimentArray);
experimentsTabs.mockGetExperiments(mockExperiments);
experimentsTabs.visit(projectName);
});

Expand All @@ -69,19 +57,56 @@ describe('Pipeline Experiments', () => {
// Verify initial run rows exist
experimentsTabs.getActiveExperimentsTable().findRows().should('have.length', 3);

// Select the "Name" filter, enter a value to filter by
// Select the "Experiment" filter, enter a value to filter by
experimentsTabs.getActiveExperimentsTable().selectFilterByName('Experiment');
experimentsTabs.getActiveExperimentsTable().findFilterTextField().type('Test experiment 2');

// Mock runs (filtered by typed run name)
// Mock experiments (filtered by typed experiment name)
experimentsTabs.mockGetExperiments(
mockExperimentArray.filter((exp) => exp.display_name.includes('Test experiment 2')),
mockExperiments.filter((exp) => exp.display_name.includes('Test experiment 2')),
);

// Verify only rows with the typed run name exist
// Verify only rows with the typed experiment name exist
experimentsTabs.getActiveExperimentsTable().findRows().should('have.length', 1);
experimentsTabs.getActiveExperimentsTable().findRowByName('Test experiment 2');
});

describe('Runs page', () => {
const activeExperimentsTable = experimentsTabs.getActiveExperimentsTable();
const [mockExperiment] = mockExperiments;

beforeEach(() => {
activeExperimentsTable.findRowByName(mockExperiment.display_name).find('a').click();
});

it('navigates to the runs page when clicking an experiment name', () => {
verifyRelativeURL(`/experiments/${projectName}/${mockExperiment.experiment_id}/runs`);
cy.findByLabelText('Breadcrumb').findByText('Experiments');
});

it('has "Experiment" value pre-filled when on the "Create run" page', () => {
pipelineRunsGlobal.findCreateRunButton().click();
cy.findByLabelText('Experiment').contains(mockExperiment.display_name);
});

it('navigates back to experiments from "Create run" page breadcrumb', () => {
pipelineRunsGlobal.findCreateRunButton().click();
cy.findByLabelText('Breadcrumb').findByText(`Experiments - ${projectName}`).click();
verifyRelativeURL(`/experiments/${projectName}`);
});

it('navigates back to experiment runs page from "Create run" page breadcrumb', () => {
pipelineRunsGlobal.findCreateRunButton().click();
cy.findByLabelText('Breadcrumb').findByText(mockExperiment.display_name).click();
verifyRelativeURL(`/experiments/${projectName}/${mockExperiment.experiment_id}/runs`);
});

it('has "Experiment" value pre-filled when on the "Schedule run" page', () => {
pipelineRunsGlobal.findSchedulesTab().click();
pipelineRunsGlobal.findScheduleRunButton().click();
cy.findByLabelText('Experiment').contains(mockExperiment.display_name);
});
});
});

const initIntercepts = () => {
Expand Down Expand Up @@ -113,7 +138,9 @@ const initIntercepts = () => {
{
pathname: '/api/k8s/apis/project.openshift.io/v1/projects',
},
mockK8sResourceList([mockProjectK8sResource({ k8sName: projectName })]),
mockK8sResourceList([
mockProjectK8sResource({ k8sName: projectName, displayName: projectName }),
]),
);

cy.intercept(
Expand All @@ -134,6 +161,21 @@ const initIntercepts = () => {
{
pathname: '/api/proxy/apis/v2beta1/runs',
},
{ runs },
{ runs: [] },
);
cy.intercept(
{
method: 'POST',
pathname: '/api/proxy/apis/v2beta1/recurringruns',
},
{
recurringRuns: [],
},
);
cy.intercept(
{
pathname: `/api/proxy/apis/v2beta1/experiments/${mockExperiments[0].experiment_id}`,
},
mockExperiments[0],
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ describe('Pipeline create runs', () => {
.as('refreshRecurringRuns');

// Navigate to the 'Create run' page
pipelineRunsGlobal.findCreateScheduleButton().click();
pipelineRunsGlobal.findScheduleRunButton().click();
verifyRelativeURL(`/pipelineRuns/${projectName}/pipelineRun/create?runType=scheduled`);
createSchedulePage.find();

Expand Down Expand Up @@ -537,7 +537,7 @@ describe('Pipeline create runs', () => {
});

it('shows cron & periodic fields', () => {
pipelineRunsGlobal.findCreateScheduleButton().click();
pipelineRunsGlobal.findScheduleRunButton().click();

createSchedulePage.findScheduledRunTypeSelector().click();
createSchedulePage.findScheduledRunTypeSelectorPeriodic().click();
Expand All @@ -551,15 +551,15 @@ describe('Pipeline create runs', () => {
});

it('should start concurrent at the max, 10', () => {
pipelineRunsGlobal.findCreateScheduleButton().click();
pipelineRunsGlobal.findScheduleRunButton().click();

createSchedulePage.findMaxConcurrencyFieldMinus().should('be.enabled');
createSchedulePage.findMaxConcurrencyFieldPlus().should('be.disabled');
createSchedulePage.findMaxConcurrencyFieldValue().should('have.value', '10');
});

it('should allow the concurrency to update via +/-', () => {
pipelineRunsGlobal.findCreateScheduleButton().click();
pipelineRunsGlobal.findScheduleRunButton().click();

createSchedulePage.findMaxConcurrencyFieldMinus().click();
createSchedulePage.findMaxConcurrencyFieldMinus().click();
Expand All @@ -570,7 +570,7 @@ describe('Pipeline create runs', () => {
});

it('should not allow concurrency to go under or above the bounds', () => {
pipelineRunsGlobal.findCreateScheduleButton().click();
pipelineRunsGlobal.findScheduleRunButton().click();

createSchedulePage.findMaxConcurrencyFieldValue().fill('0');
createSchedulePage.findMaxConcurrencyFieldValue().should('have.value', 1);
Expand All @@ -580,7 +580,7 @@ describe('Pipeline create runs', () => {
});

it('should hide and show date toggles', () => {
pipelineRunsGlobal.findCreateScheduleButton().click();
pipelineRunsGlobal.findScheduleRunButton().click();

createSchedulePage.findStartDatePickerDate().should('not.be.visible');
createSchedulePage.findStartDatePickerTime().should('not.be.visible');
Expand All @@ -596,7 +596,7 @@ describe('Pipeline create runs', () => {
});

it('should see catch up is enabled by default', () => {
pipelineRunsGlobal.findCreateScheduleButton().click();
pipelineRunsGlobal.findScheduleRunButton().click();

createSchedulePage.findCatchUpSwitchValue().should('be.checked');
createSchedulePage.findCatchUpSwitch().click();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -257,14 +257,14 @@ describe('Pipeline runs', () => {
});

describe('Table filter', () => {
it('filter by run name', () => {
it('filter by name', () => {
// Verify initial run rows exist
activeRunsTable.findRows().should('have.length', 3);

// Select the "Name" filter, enter a value to filter by
// Select the "Run" filter, enter a value to filter by
pipelineRunsGlobal
.findActiveRunsToolbar()
.within(() => pipelineRunsGlobal.selectFilterByName('Name'));
.within(() => pipelineRunsGlobal.selectFilterByName('Run'));
pipelineRunsGlobal
.findActiveRunsToolbar()
.within(() => pipelineRunFilterBar.findNameInput().type('run 1'));
Expand Down Expand Up @@ -504,7 +504,7 @@ describe('Pipeline runs', () => {
});

it('navigate to create run page', () => {
pipelineRunsGlobal.findCreateScheduleButton().click();
pipelineRunsGlobal.findScheduleRunButton().click();
verifyRelativeURL(`/pipelineRuns/${projectName}/pipelineRun/create?runType=scheduled`);
});
});
Expand Down Expand Up @@ -536,7 +536,7 @@ describe('Pipeline runs', () => {

describe('Navigation', () => {
it('navigate to create scheduled run page', () => {
pipelineRunsGlobal.findCreateScheduleButton().click();
pipelineRunsGlobal.findScheduleRunButton().click();
verifyRelativeURL(`/pipelineRuns/${projectName}/pipelineRun/create?runType=scheduled`);
});
it('navigate to clone scheduled run page', () => {
Expand All @@ -561,8 +561,8 @@ describe('Pipeline runs', () => {
// Verify initial job rows exist
pipelineRunJobTable.findRows().should('have.length', 3);

// Select the "Name" filter, enter a value to filter by
pipelineRunJobTable.selectFilterByName('Name');
// Select the "Schedule" filter, enter a value to filter by
pipelineRunJobTable.selectFilterByName('Schedule');
pipelineRunJobTable.findFilterTextField().type('test-pipeline');

// Mock jobs (filtered by typed job name)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ describe('Pipelines', () => {
pipelinesTable.findRowByName('New pipeline version');
});

it.only('delete a single pipeline', () => {
it('delete a single pipeline', () => {
createDeletePipelineIntercept(initialMockPipeline.pipeline_id).as('deletePipeline');
pipelinesTable.mockGetPipelineVersions([], initialMockPipeline.pipeline_id);
pipelinesGlobal.visit(projectName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ const initIntercepts = () => {
cy.intercept(
{
method: 'POST',
pathname: `/api/proxy/apis/v2beta1/runs/`,
pathname: '/api/proxy/apis/v2beta1/runs',
},
{ runs: [mockRun] },
);
Expand Down Expand Up @@ -184,37 +184,30 @@ describe('Pipeline topology', () => {
describe('Navigation', () => {
beforeEach(() => {
initIntercepts();
pipelineDetails.visit(projectId, mockVersion.pipeline_id, mockVersion.pipeline_version_id);
// https://issues.redhat.com/browse/RHOAIENG-4562
// Bypass intermittent Cypress error:
// Failed to execute 'importScripts' on 'WorkerGlobalScope': The script at 'https://cdn.jsdelivr.net/npm/[email protected]/min/vs/base/worker/workerMain.js' failed to load.
Cypress.on('uncaught:exception', () => false);
});

it('Test pipeline details create run navigation', () => {
pipelineDetails.visit(projectId, mockVersion.pipeline_id, mockVersion.pipeline_version_id);
pipelineDetails.findActionsDropdown().click();
cy.findByText('Create run').click();
pipelineDetails.selectActionDropdownItem('Create run');
verifyRelativeURL(`/pipelineRuns/${projectId}/pipelineRun/create`);
});

it('navigates to "Schedule run" page on "Schedule run" click', () => {
pipelineDetails.visit(projectId, mockVersion.pipeline_id, mockVersion.pipeline_version_id);
pipelineDetails.findActionsDropdown().click();
cy.findByText('Schedule run').click();
pipelineDetails.selectActionDropdownItem('Schedule run');
verifyRelativeURL(`/pipelineRuns/${projectId}/pipelineRun/create?runType=scheduled`);
});

it('Test pipeline details view runs navigation', () => {
pipelineDetails.visit(projectId, mockVersion.pipeline_id, mockVersion.pipeline_version_id);
pipelineDetails.findActionsDropdown().click();
cy.findByText('View runs').click();
pipelineDetails.selectActionDropdownItem('View runs');
verifyRelativeURL(`/pipelineRuns/${projectId}?runType=active`);
});

it('navigates to "Schedules" on "View schedules" click', () => {
pipelineDetails.visit(projectId, mockVersion.pipeline_id, mockVersion.pipeline_version_id);
pipelineDetails.findActionsDropdown().click();
cy.findByText('View schedules').click();
pipelineDetails.selectActionDropdownItem('View schedules');
verifyRelativeURL(`/pipelineRuns/${projectId}?runType=scheduled`);
});
});
Expand All @@ -228,15 +221,13 @@ describe('Pipeline topology', () => {

it('Test pipeline run duplicate navigation', () => {
pipelineRunDetails.visit(projectId, mockRun.run_id);
pipelineRunDetails.findActionsDropdown().click();
cy.findByText('Duplicate').click();
pipelineRunDetails.selectActionDropdownItem('Duplicate');
verifyRelativeURL(`/pipelineRuns/${projectId}/pipelineRun/clone/${mockRun.run_id}`);
});

it('Test pipeline job duplicate navigation', () => {
pipelineRunJobDetails.visit(projectId, mockJob.recurring_run_id);
pipelineRunJobDetails.findActionsDropdown().click();
cy.findByText('Duplicate run').click();
pipelineRunJobDetails.selectActionDropdownItem('Duplicate');
verifyRelativeURL(
`/pipelineRuns/${projectId}/pipelineRun/cloneJob/${mockJob.recurring_run_id}?runType=scheduled`,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ import { ExperimentKFv2 } from '~/concepts/pipelines/kfTypes';

class ExperimentsTabs {
visit(namespace?: string, tab?: string) {
cy.visitWithLogin(
`/pipelineExperiments${namespace ? `/${namespace}` : ''}${tab ? `/${tab}` : ''}`,
);
cy.visitWithLogin(`/experiments${namespace ? `/${namespace}` : ''}${tab ? `/${tab}` : ''}`);
this.wait();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ class PipelineRunsGlobal {
}

findActiveRunsTab() {
return cy.findByRole('tab', { name: 'Active runs tab' });
return cy.findByRole('tab', { name: 'Active tab' });
}

findArchivedRunsTab() {
return cy.findByRole('tab', { name: 'Archived runs tab' });
return cy.findByRole('tab', { name: 'Archived tab' });
}

findProjectSelect() {
Expand All @@ -40,7 +40,7 @@ class PipelineRunsGlobal {
return cy.findByRole('button', { name: 'Create run' });
}

findCreateScheduleButton() {
findScheduleRunButton() {
return cy.findByRole('button', { name: 'Schedule run' });
}

Expand Down
Loading

0 comments on commit d7e0468

Please sign in to comment.