Skip to content

Commit

Permalink
Add Cypress page object for the component
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewballantyne committed Sep 8, 2024
1 parent c10e74f commit 66eb345
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 35 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
export class K8sNameDescriptionField {
constructor(private compTestId: string) {}

private findByScopedTestId(suffix: string): Cypress.Chainable<JQuery<HTMLElement>> {
return cy.findByTestId(`${this.compTestId}-${suffix}`);
}

findDisplayNameInput(): Cypress.Chainable<JQuery<HTMLElement>> {
return this.findByScopedTestId('name');
}

findDescriptionInput(): Cypress.Chainable<JQuery<HTMLElement>> {
return this.findByScopedTestId('description');
}

findResourceEditLink(): Cypress.Chainable<JQuery<HTMLElement>> {
return this.findByScopedTestId('editResourceLink');
}

findResourceNameInput(): Cypress.Chainable<JQuery<HTMLElement>> {
return this.findByScopedTestId('resourceName');
}
}
13 changes: 3 additions & 10 deletions frontend/src/__tests__/cypress/cypress/pages/projects.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Modal } from '~/__tests__/cypress/cypress/pages/components/Modal';
import { appChrome } from '~/__tests__/cypress/cypress/pages/appChrome';
import { DeleteModal } from '~/__tests__/cypress/cypress/pages/components/DeleteModal';
import { K8sNameDescriptionField } from '~/__tests__/cypress/cypress/pages/components/K8sNameDescriptionField';
import { TableRow } from './components/table';
import { TableToolbar } from './components/TableToolbar';

Expand Down Expand Up @@ -112,16 +113,8 @@ class CreateEditProjectModal extends Modal {
super(`${edit ? 'Edit' : 'Create'} data science project`);
}

findNameInput() {
return this.find().findByTestId('manage-project-modal-name');
}

findResourceNameInput() {
return this.find().findByTestId('resource-manage-project-modal-name');
}

findDescriptionInput() {
return this.find().findByTestId('manage-project-modal-description');
getK8sNameDescriptionFields() {
return new K8sNameDescriptionField('manage-project-modal');
}

findSubmitButton() {
Expand Down
9 changes: 3 additions & 6 deletions frontend/src/__tests__/cypress/cypress/pages/workbench.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { K8sNameDescriptionField } from '~/__tests__/cypress/cypress/pages/components/K8sNameDescriptionField';
import { Contextual } from './components/Contextual';
import { Modal } from './components/Modal';
import { TableRow } from './components/table';
Expand Down Expand Up @@ -219,12 +220,8 @@ class CreateSpawnerPage {
return cy.findByTestId('submit-button');
}

findNameInput() {
return cy.findByTestId('workbench-name');
}

findDescriptionInput() {
return cy.findByTestId('workbench-description');
getK8sNameDescriptionFields() {
return new K8sNameDescriptionField('workbench');
}

getEnvironmentVariableTypeField(index: number) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,15 @@ describe('Data Science Projects', { testIsolation: false }, () => {
});

it('should create project', () => {
createProjectModal.findNameInput().type('My Test Project');
createProjectModal.findDescriptionInput().type('Test project description.');
const fields = createProjectModal.getK8sNameDescriptionFields();
fields.findDisplayNameInput().type('My Test Project');
fields.findDescriptionInput().type('Test project description.');
createProjectModal.findSubmitButton().should('be.enabled');
createProjectModal.findResourceNameInput().should('have.value', 'my-test-project').clear();
createProjectModal.findResourceNameInput().should('have.attr', 'aria-invalid', 'true');
fields.findResourceEditLink().click();
fields.findResourceNameInput().should('have.value', 'my-test-project').clear();
fields.findResourceNameInput().should('have.attr', 'aria-invalid', 'true');
createProjectModal.findSubmitButton().should('be.disabled');
createProjectModal.findResourceNameInput().type('test-project');
fields.findResourceNameInput().type('test-project');

cy.interceptSnapshot('/api/k8s/apis/project.openshift.io/v1/projects', 'projects-1');
cy.interceptSnapshot('/api/namespaces/test-project/0', 'update-project');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,16 @@ describe('Data science projects details', () => {
createProjectModal.shouldBeOpen();
createProjectModal.findSubmitButton().should('be.disabled');

createProjectModal.findNameInput().type('My Test Project');
createProjectModal.findDescriptionInput().type('Test project description.');
const fields = createProjectModal.getK8sNameDescriptionFields();
fields.findDisplayNameInput().type('My Test Project');
fields.findDescriptionInput().type('Test project description.');
createProjectModal.findSubmitButton().should('be.enabled');
createProjectModal.findResourceNameInput().should('have.value', 'my-test-project').clear();
createProjectModal.findResourceNameInput().should('have.attr', 'aria-invalid', 'true');
fields.findResourceEditLink().click();
fields.findResourceNameInput().should('have.value', 'my-test-project');
fields.findResourceNameInput().clear().type('InVaLiD vAlUe!');
fields.findResourceNameInput().should('have.attr', 'aria-invalid', 'true');
createProjectModal.findSubmitButton().should('be.disabled');
createProjectModal.findResourceNameInput().type('test-project');
fields.findResourceNameInput().clear().type('test-project');

createProjectModal.findSubmitButton().click();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,9 @@ describe('Workbench page', () => {
workbenchPage.findCreateButton().click();
createSpawnerPage.findSubmitButton().should('be.disabled');
verifyRelativeURL('/projects/test-project/spawner');
createSpawnerPage.findNameInput().fill('test-project');
createSpawnerPage.findDescriptionInput().fill('test-description');
const nameDesc = createSpawnerPage.getK8sNameDescriptionFields();
nameDesc.findDisplayNameInput().fill('test-project');
nameDesc.findDescriptionInput().fill('test-description');
//to check scrollable dropdown selection
createSpawnerPage.findNotebookImage('test-9').click();
createSpawnerPage.selectContainerSize(
Expand Down Expand Up @@ -353,8 +354,9 @@ describe('Workbench page', () => {
workbenchPage.findCreateButton().click();
createSpawnerPage.findSubmitButton().should('be.disabled');
verifyRelativeURL('/projects/test-project/spawner');
createSpawnerPage.findNameInput().fill('1234');
createSpawnerPage.findDescriptionInput().fill('test-description');
const nameDesc = createSpawnerPage.getK8sNameDescriptionFields();
nameDesc.findDisplayNameInput().fill('1234');
nameDesc.findDescriptionInput().fill('test-description');
//to check scrollable dropdown selection
createSpawnerPage.findNotebookImage('test-9').click();
createSpawnerPage.selectContainerSize(
Expand Down Expand Up @@ -547,12 +549,13 @@ describe('Workbench page', () => {
mockK8sResourceList([mockPVCK8sResource({ name: 'test-notebook' })]),
);
editSpawnerPage.visit('test-notebook');
editSpawnerPage.findNameInput().should('have.value', 'Test Notebook');
const nameDesc = editSpawnerPage.getK8sNameDescriptionFields();
nameDesc.findDisplayNameInput().should('have.value', 'Test Notebook');
editSpawnerPage.shouldHaveNotebookImageSelectInput('Test Image');
editSpawnerPage.shouldHaveContainerSizeInput('Small');
editSpawnerPage.shouldHavePersistentStorage('Test Storage');
editSpawnerPage.findSubmitButton().should('be.enabled');
editSpawnerPage.findNameInput().fill('Updated Notebook');
nameDesc.findDisplayNameInput().fill('Updated Notebook');

cy.interceptK8s('PUT', NotebookModel, mockNotebookK8sResource({})).as('editWorkbench');
editSpawnerPage.findSubmitButton().click();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import * as React from 'react';
import { FormGroup, HelperText, StackItem, TextInput } from '@patternfly/react-core';
import {
FormGroup,
HelperText,
StackItem,
TextInput,
ValidatedOptions,
} from '@patternfly/react-core';
import ResourceNameDefinitionTooltip from '~/concepts/k8s/ResourceNameDefinitionTooltip';
import {
HelperTextItemMaxLength,
Expand All @@ -17,7 +23,7 @@ type ResourceNameFieldProps = {
onDataChange: K8sNameDescriptionFieldUpdateFunction;
};

/** Sub-resource; not for public cunsumption */
/** Sub-resource; not for public consumption */
const ResourceNameField: React.FC<ResourceNameFieldProps> = ({
allowEdit,
dataTestId,
Expand All @@ -42,14 +48,25 @@ const ResourceNameField: React.FC<ResourceNameFieldProps> = ({
return null;
}

let validated: ValidatedOptions = ValidatedOptions.default;
if (k8sName.state.invalidLength || k8sName.state.invalidCharacters) {
validated = ValidatedOptions.error;
} else if (k8sName.state.autoTrimmed) {
validated = ValidatedOptions.warning;

Check warning on line 55 in frontend/src/concepts/k8s/K8sNameDescriptionField/ResourceNameField.tsx

View check run for this annotation

Codecov / codecov/patch

frontend/src/concepts/k8s/K8sNameDescriptionField/ResourceNameField.tsx#L55

Added line #L55 was not covered by tests
} else if (k8sName.value.length > 0) {
validated = ValidatedOptions.success;
}

return (
<StackItem>
<FormGroup {...formGroupProps}>
<FormGroup {...formGroupProps} isRequired>
<TextInput
data-testid={`${dataTestId}-resourceName`}
name={`${dataTestId}-resourceName`}
isRequired
value={k8sName.value}
onChange={(event, value) => onDataChange('k8sName', value)}
validated={validated}
/>
<HelperText>
<HelperTextItemMaxLength k8sName={k8sName} />
Expand Down

0 comments on commit 66eb345

Please sign in to comment.