Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RHOAIENG-2985] Experiments - Run Integration #2601

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -379,13 +379,8 @@ describe('Pipeline create runs', () => {
mockPipelineVersion.pipeline_id,
);

// Mock jobs list with newly created job
pipelineRunJobTable
.mockGetJobs([...initialMockRecurringRuns, buildMockJobKF(createRecurringRunParams)])
.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 @@ -433,16 +428,10 @@ describe('Pipeline create runs', () => {
});
});

// Should show newly created schedule in the table
cy.wait('@refreshRecurringRuns').then((interception) => {
expect(interception.request.body).to.eql({
path: '/apis/v2beta1/recurringruns',
method: 'GET',
host: 'https://ds-pipeline-pipelines-definition-test-project-name.apps.user.com',
queryParams: { sort_by: 'created_at desc', page_size: 10 },
});
});
pipelineRunJobTable.findRowByName('New job');
// Should be redirected to the schedule details page
verifyRelativeURL(
`/pipelineRuns/${projectName}/pipelineRunJob/view/${createRecurringRunParams.recurring_run_id}`,
);
});

it('duplicates a schedule', () => {
Expand All @@ -466,11 +455,6 @@ describe('Pipeline create runs', () => {
cloneSchedulePage.mockGetPipeline(mockPipeline);
cloneSchedulePage.mockGetExperiment(mockExperiment);

// Mock jobs list with newly cloned job
pipelineRunJobTable
.mockGetJobs([...initialMockRecurringRuns, mockDuplicateRecurringRun])
.as('refreshRecurringRuns');

// Navigate to clone run page for a given schedule
pipelineRunJobTable.selectRowActionByName(mockRecurringRun.display_name, 'Duplicate');
verifyRelativeURL(
Expand Down Expand Up @@ -523,21 +507,14 @@ describe('Pipeline create runs', () => {
});
});

// Should show newly cloned schedule in the table
cy.wait('@refreshRecurringRuns').then((interception) => {
expect(interception.request.body).to.eql({
path: '/apis/v2beta1/recurringruns',
method: 'GET',
host: 'https://ds-pipeline-pipelines-definition-test-project-name.apps.user.com',
queryParams: { sort_by: 'created_at desc', page_size: 10 },
});
});

pipelineRunJobTable.findRowByName('Duplicate of Test job');
// Should be redirected to the schedule details page
verifyRelativeURL(
`/pipelineRuns/${projectName}/pipelineRunJob/view/${mockDuplicateRecurringRun.recurring_run_id}`,
);
});

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

createSchedulePage.findScheduledRunTypeSelector().click();
createSchedulePage.findScheduledRunTypeSelectorPeriodic().click();
Expand All @@ -551,15 +528,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 +547,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 +557,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 +573,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
Loading
Loading