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

Refactor VM node selector scenario #5742

Merged
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/* eslint-disable no-await-in-loop */
import * as view from '../../views/dialogs/editNodeSelectorView';
import { fillInput } from '@console/shared/src/test-utils/utils';
import { click } from '@console/dev-console/integration-tests/utilities/elementInteractions';
import { MatchLabels } from '@console/internal/module/k8s';

export class NodeSelectorDialog {
private extractID(id: string) {
return id.split('-')[1];
}

/**
* Adds new row if needed.
* Returns string with index of next empty row.
*/
async addRow(): Promise<string> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other place like Tolerations and affinity may use addRow as well, then we can move it to utils or console-shared.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better place would probably be some scheduling.dialog.view.ts file, utils and console-shared are for more general purpose utility methods

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay, if you decide not to do it in this one, then it looks good to me.

if ((await view.emptyKeyInputs.count()) === 0) {
await click(view.addLabelBtn);
}
return this.extractID(await view.emptyKeyInputs.first().getAttribute('id'));
}

async addLabel(key: string, value: string) {
const id = await this.addRow();
await fillInput(view.labelKeyInputByID(id), key);
await fillInput(view.labelValueInputByID(id), value);
}

async addLabels(labels: MatchLabels) {
for (const [key, value] of Object.entries(labels)) {
await this.addLabel(key, value);
}
}

async deleteLabel(key: string) {
const id = this.extractID(await view.keyInputByKey(key).getAttribute('id'));
await click(view.deleteBtnByID(id));
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
/* eslint-disable no-await-in-loop, no-console */
import { browser } from 'protractor';
import { waitForStringNotInElement } from '@console/shared/src/test-utils/utils';
import { browser, ExpectedConditions as until } from 'protractor';
import {
waitForStringNotInElement,
click,
asyncForEach,
} from '@console/shared/src/test-utils/utils';
import { detailViewAction, listViewAction } from '@console/shared/src/test-utils/actions.view';
import { VirtualMachineModel } from '@console/kubevirt-plugin/src/models';
import * as vmView from '../../views/virtualMachine.view';
import { VM_MIGRATION_TIMEOUT_SECS, VM_ACTION, TAB, VM_STATUS } from '../utils/consts';
import {
VM_MIGRATION_TIMEOUT_SECS,
VM_ACTION,
TAB,
VM_STATUS,
PAGE_LOAD_TIMEOUT_SECS,
} from '../utils/consts';
import { BaseVirtualMachine } from './baseVirtualMachine';
import { NodeSelectorDialog } from '../dialogs/nodeSelectorDialog';
import { saveButton } from '../../views/kubevirtUIResource.view';
import { annotationDialogOverlay } from '@console/internal-integration-tests/views/modal-annotations.view';
import { MatchLabels } from '@console/internal/module/k8s';

const noConfirmDialogActions: VM_ACTION[] = [VM_ACTION.Start, VM_ACTION.Clone];

Expand Down Expand Up @@ -39,4 +53,28 @@ export class VirtualMachine extends BaseVirtualMachine {
timeout,
);
}

async addNodeSelectors(labels: MatchLabels) {
Copy link
Contributor

@gouyang gouyang Jun 18, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it better to move addNodeSelectors and deleteNodeSelectors to kubevirtUIResource.ts?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, scheduling is relevant for Virtual Machine only, it cannot be edited in VMI or Virtual Machine Templates

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay.

const nodeSelectorDialog = new NodeSelectorDialog();
await this.navigateToDetail();
await this.modalEditNodeSelector();
await nodeSelectorDialog.addLabels(labels);
await click(saveButton);
await browser.wait(until.invisibilityOf(annotationDialogOverlay), PAGE_LOAD_TIMEOUT_SECS);
}

async deleteNodeSelector(key: string) {
const nodeSelectorDialog = new NodeSelectorDialog();
await this.navigateToDetail();
await this.modalEditNodeSelector();
await nodeSelectorDialog.deleteLabel(key);
await click(saveButton);
await browser.wait(until.invisibilityOf(annotationDialogOverlay), PAGE_LOAD_TIMEOUT_SECS);
}

async deleteNodeSelectors(keys: string[]) {
return asyncForEach(keys, async (key: string) => {
await this.deleteNodeSelector(key);
});
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import { browser, ExpectedConditions as until } from 'protractor';
import { testName } from '@console/internal-integration-tests/protractor.conf';
import { createResource, deleteResource, click } from '@console/shared/src/test-utils/utils';
import * as editNodeSelectorView from '../views/dialogs/editNodeSelectorView';
import { createResource, deleteResource } from '@console/shared/src/test-utils/utils';
import * as virtualMachineView from '../views/virtualMachine.view';
import { saveButton } from '../views/kubevirtUIResource.view';
import { VM_CREATE_AND_EDIT_TIMEOUT_SECS } from './utils/consts';
import { VirtualMachine } from './models/virtualMachine';
import { getVMManifest } from './utils/mocks';
import { getRandStr } from './utils/utils';
import { MatchLabels } from '@console/internal/module/k8s';

describe('KubeVirt VM detail - edit Node Selector', () => {
const testVM = getVMManifest('Container', testName, `node-selector-vm-${getRandStr(5)}`);
const vm = new VirtualMachine(testVM.metadata);
const vm: VirtualMachine = new VirtualMachine(testVM.metadata);
const labels: MatchLabels = {
Copy link
Contributor

@gouyang gouyang Jun 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest adding at least two labels for this tests to make sure it works well. And then refactor deleteLabel to deleteLabels.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated, adding and removing 2 key:value labels, added deleteNodeSelectors method.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.

key1: 'value1',
key2: 'value2',
};

beforeAll(async () => {
createResource(testVM);
Expand All @@ -24,23 +27,20 @@ describe('KubeVirt VM detail - edit Node Selector', () => {
it(
'ID(CNV-4133) Adds a Node Selector, then removes it',
async () => {
await vm.navigateToDetail();
await vm.modalEditNodeSelector();
await click(editNodeSelectorView.addLabelBtn);
await editNodeSelectorView.labelKeyInputByID(0).sendKeys('key');
await editNodeSelectorView.labelValueInputByID(0).sendKeys('value');
await click(saveButton);

await vm.addNodeSelectors(labels);
await browser.wait(
until.textToBePresentInElement(
virtualMachineView.vmDetailNodeSelector(vm.namespace, vm.name),
'key=value',
until.and(
until.textToBePresentInElement(
virtualMachineView.vmDetailNodeSelector(vm.namespace, vm.name),
`key1=${labels.key1}`,
),
until.textToBePresentInElement(
virtualMachineView.vmDetailNodeSelector(vm.namespace, vm.name),
`key2=${labels.key2}`,
),
),
);

await vm.modalEditNodeSelector();
await click(editNodeSelectorView.deleteBtnByID(0));
await click(saveButton);
await vm.deleteNodeSelectors(Object.keys(labels));
await browser.wait(
until.textToBePresentInElement(
virtualMachineView.vmDetailNodeSelector(vm.namespace, vm.name),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { $ } from 'protractor';
import { $, $$ } from 'protractor';

export const addLabelBtn = $('#vm-labels-list-add-btn');
export const emptyKeyInputs = $$("input[placeholder='key'][value='']");
export const keyInputByKey = (key) => $(`input[placeholder='key'][value='${key}']`);
export const labelKeyInputByID = (id) => $(`#label-${id}-key-input`);
export const labelValueInputByID = (id) => $(`#label-${id}-value-input`);
export const deleteBtnByID = (id) => $(`#label-${id}-delete-btn`);