Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ const KeyTreeSettings = ({ loading }: Props) => {
<EuiButton
size="s"
color="secondary"
data-testid="tree-view-cancel-btn"
onClick={closePopover}
>
Cancel
Expand Down
75 changes: 72 additions & 3 deletions tests/e2e/common-actions/browser-actions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Selector, t} from 'testcafe';
import { Selector, t } from 'testcafe';
import { BrowserPage } from '../pageObjects';

const browserPage = new BrowserPage();
Expand Down Expand Up @@ -29,6 +29,7 @@ export class BrowserActions {
}
}
}

/**
* Verify tooltip contains text
* @param expectedText Expected link that is compared with actual
Expand All @@ -39,17 +40,85 @@ export class BrowserActions {
? await t.expect(browserPage.tooltip.textContent).contains(expectedText, `"${expectedText}" Text is incorrect in tooltip`)
: await t.expect(browserPage.tooltip.textContent).notContains(expectedText, `Tooltip still contains text "${expectedText}"`);
}

/**
* Verify that the new key is displayed at the top of the list of keys and opened and pre-selected in List view
* */
* @param keyName Key name
*/
async verifyKeyDisplayedTopAndOpened(keyName: string): Promise<void> {
await t.expect(Selector('[aria-rowindex="1"]').withText(keyName).visible).ok(`element with ${keyName} is not visible in the top of list`);
await t.expect(browserPage.keyNameFormDetails.withText(keyName).visible).ok(`element with ${keyName} is not opened`);
}

/**
* Verify that the new key is not displayed at the top of the list of keys and opened and pre-selected in List view
* */
* @param keyName Key name
*/
async verifyKeyIsNotDisplayedTop(keyName: string): Promise<void> {
await t.expect(Selector('[aria-rowindex="1"]').withText(keyName).exists).notOk(`element with ${keyName} is not visible in the top of list`);
}

/**
* Verify that not patterned keys not visible with delimiter
* @param delimiter string with delimiter value
*/
async verifyNotPatternedKeys(delimiter: string): Promise<void> {
const notPatternedKeys = Selector('[data-testid^="badge"]').parent('[data-testid^="node-item_"]');
const notPatternedKeysNumber = await notPatternedKeys.count;

for (let i = 0; i < notPatternedKeysNumber; i++) {
await t.expect(notPatternedKeys.nth(i).withText(delimiter).exists).notOk('Not contained delimiter keys');
}
}

/**
* Get node name by folders
* @param startFolder start folder
* @param folderName name of folder
* @param delimiter string with delimiter value
*/
getNodeName(startFolder: string, folderName: string, delimiter: string): string {
return startFolder + folderName + delimiter;

}

/**
* Get node selector by name
* @param name node name
*/
getNodeSelector(name: string): Selector {
return Selector(`[data-testid="node-item_${name}"]`);
}

/**
* Check tree view structure
* @param folders name of folders for tree view build
* @param delimiter string with delimiter value
*/
async checkTreeViewFoldersStructure(folders: string[][], delimiter: string): Promise<void> {
// Verify not patterned keys
await this.verifyNotPatternedKeys(delimiter);

const foldersNumber = folders.length;

for (let i = 0; i < foldersNumber; i++) {
const innerFoldersNumber = folders[i].length;
let prevNodeSelector = '';

for (let j = 0; j < innerFoldersNumber; j++) {
const nodeName = this.getNodeName(prevNodeSelector, folders[i][j], delimiter);
const node = this.getNodeSelector(nodeName);
await t.click(node);
prevNodeSelector = nodeName;
}

// Verify that the last folder level contains required keys
const foundKeyName = `${folders[i].join(delimiter)}`;
const firstFolderName = this.getNodeName('', folders[i][0], delimiter);
const firstFolder = this.getNodeSelector(firstFolderName);
await t
.expect(Selector(`[data-testid*="node-item_${foundKeyName}"]`).find('[data-testid^="key-"]').exists).ok('Specific key not found')
.click(firstFolder);
}
}
}
1 change: 1 addition & 0 deletions tests/e2e/desktop.runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import testcafe from 'testcafe';
selectorTimeout: 5000,
assertionTimeout: 5000,
speed: 1,
quarantineMode: { successThreshold: 1, attemptLimit: 3 },
});
})
.then((failedCount) => {
Expand Down
1 change: 1 addition & 0 deletions tests/e2e/desktop.runner.win.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import testcafe from 'testcafe';
selectorTimeout: 5000,
assertionTimeout: 5000,
speed: 1,
quarantineMode: { successThreshold: 1, attemptLimit: 3 },
});
})
.then((failedCount) => {
Expand Down
19 changes: 5 additions & 14 deletions tests/e2e/helpers/keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -249,29 +249,20 @@ export async function deleteAllKeysFromDB(host: string, port: string): Promise<v
/**
* Verifying if the Keys are in the List of keys
* @param keyNames The names of the keys
* @param isDisplayed True if keys should be displayed
*/
export async function verifyKeysDisplayedInTheList(keyNames: string[]): Promise<void> {
export async function verifyKeysDisplayingInTheList(keyNames: string[], isDisplayed: boolean): Promise<void> {
for (const keyName of keyNames) {
await t.expect(browserPage.getKeySelectorByName(keyName).exists).ok(`The key ${keyName} not found`);
}
}

/**
* Verifying if the Keys are not in the List of keys
* @param keyNames The names of the keys
*/

export async function verifyKeysNotDisplayedInTheList(keyNames: string[]): Promise<void> {
for (const keyName of keyNames) {
await t.expect(await browserPage.isKeyIsDisplayedInTheList(keyName)).notOk(`The key ${keyName} found`);
isDisplayed
? await t.expect(browserPage.getKeySelectorByName(keyName).exists).ok(`The key ${keyName} not found`)
: await t.expect(await browserPage.isKeyIsDisplayedInTheList(keyName)).notOk(`The key ${keyName} found`);
}
}

/**
* Verify search/filter value
* @param value The value in search/filter input
*/

export async function verifySearchFilterValue(value: string): Promise<void> {
await t.expect(browserPage.filterByPatterSearchInput.withAttribute('value', value).exists).ok(`Filter per key name ${value} is not applied/correct`);
}
115 changes: 12 additions & 103 deletions tests/e2e/pageObjects/browser-page.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { t, Selector } from 'testcafe';
import { Common } from '../helpers/common';
import { InstancePage } from './instance-page';
import { BulkActions } from './components/browser';
import { BulkActions, TreeView } from './components/browser';

export class BrowserPage extends InstancePage {
BulkActions = new BulkActions();
TreeView = new TreeView();

//CSS Selectors
cssSelectorGrid = '[aria-label="grid"]';
Expand Down Expand Up @@ -71,13 +72,9 @@ export class BrowserPage extends InstancePage {
databaseInfoIcon = Selector('[data-testid=db-info-icon]');
treeViewButton = Selector('[data-testid=view-type-list-btn]');
browserViewButton = Selector('[data-testid=view-type-browser-btn]');
treeViewSeparator = Selector('[data-testid=tree-view-delimiter-btn]');
searchButton = Selector('[data-testid=search-btn]');
clearFilterButton = Selector('[data-testid=reset-filter-btn]');
clearSelectionButton = Selector('[data-testid=clear-selection-btn]');
treeViewDelimiterButton = Selector('[data-testid=tree-view-delimiter-btn]');
treeViewDelimiterValueSave = Selector('[data-testid=apply-btn]');
treeViewDelimiterValueCancel = Selector('[data-testid=cancel-btn]');
fullScreenModeButton = Selector('[data-testid=toggle-full-screen]');
closeRightPanel = Selector('[data-testid=close-right-panel-btn]');
addNewStreamEntry = Selector('[data-testid=add-key-value-items-btn]');
Expand Down Expand Up @@ -177,7 +174,6 @@ export class BrowserPage extends InstancePage {
jsonKeyInput = Selector('[data-testid=json-key]');
jsonValueInput = Selector('[data-testid=json-value]');
countInput = Selector('[data-testid=count-input]');
treeViewDelimiterInput = Selector('[data-testid=tree-view-delimiter-input]');
streamEntryId = Selector('[data-testid=entryId]');
streamField = Selector('[data-testid=field-name]');
streamValue = Selector('[data-testid=field-value]');
Expand Down Expand Up @@ -212,27 +208,19 @@ export class BrowserPage extends InstancePage {
jsonError = Selector('[data-testid=edit-json-error]');
tooltip = Selector('[role=tooltip]');
noResultsFound = Selector('[data-test-subj=no-result-found]');
noResultsFoundOnly = Selector('[data-testid=no-result-found-only]');
searchAdvices = Selector('[data-test-subj=search-advices]');
keysNumberOfResults = Selector('[data-testid=keys-number-of-results]');
keysTotalNumber = Selector('[data-testid=keys-total]');
overviewConnectedClients = Selector('[data-test-subj=overview-connected-clients]');
overviewCommandsSec = Selector('[data-test-subj=overview-commands-sec]');
overviewCpu = Selector('[data-test-subj=overview-cpu]');
treeViewArea = Selector('[data-test-subj=tree-view-panel]');
scannedValue = Selector('[data-testid=keys-number-of-scanned]');
treeViewKeysNumber = Selector('[data-testid^=count_]');
treeViewPercentage = Selector('[data-testid^=percentage_]');
treeViewFolders = Selector('[data-test-subj^=node-arrow-icon_]');
totalKeysNumber = Selector('[data-testid=keys-total]');
databaseInfoToolTip = Selector('[data-testid=db-info-tooltip]');
treeViewDeviceFolder = Selector('[data-testid^=node-item_device] div');
treeViewDeviceKyesCount = Selector('[data-testid^=count_device] span');
ttlValueInKeysTable = Selector('[data-testid^=ttl-]');
stringKeyValue = Selector('.key-details-body pre');
keyDetailsBadge = Selector('.key-details-header .euiBadge__text');
treeViewKeysItem = Selector('[data-testid*="keys:keys:"]');
treeViewNotPatternedKeys = Selector('[data-testid*="node-item_keys"]');
treeViewNodeArrowIcon = Selector('[data-test-subj^=node-arrow-icon_]');
modulesTypeDetails = Selector('[data-testid=modules-type-details]');
filteringLabel = Selector('[data-testid^=badge-]');
keysSummary = Selector('[data-testid=keys-summary]');
Expand Down Expand Up @@ -590,6 +578,7 @@ export class BrowserPage extends InstancePage {

/**
* Delete Key By name after Hovering
* @param keyName The name of the key
*/
async deleteKeyByNameFromList(keyName: string): Promise<void> {
await this.searchByKeyName(keyName);
Expand Down Expand Up @@ -766,7 +755,10 @@ export class BrowserPage extends InstancePage {
.click(this.saveMemberButton);
}

//Open key details
/**
* Open key details with search
* @param keyName The name of the key
*/
async openKeyDetails(keyName: string): Promise<void> {
await this.searchByKeyName(keyName);
await t.click(this.keyNameInTheList);
Expand Down Expand Up @@ -878,66 +870,6 @@ export class BrowserPage extends InstancePage {
await t.typeText(this.jsonValueInput, jsonStructure, { replace: true, paste: true });
await t.click(this.applyEditButton);
}
/**
* Check tree view structure
* @folders name of folders for tree view build
* @delimiter string with delimiter value
* @commonKeyFolder flag if not patterned keys will be displayed
*/
async checkTreeViewFoldersStructure(folders: string[][], delimiter: string, commonKeyFolder: boolean): Promise<void> {
// Verify that all keys that are not inside of tree view doesn't contain delimiter
if (commonKeyFolder) {
await t
.expect(this.treeViewNotPatternedKeys.exists).ok('Folder with not patterned keys')
.click(this.treeViewNotPatternedKeys);
const notPatternedKeys = Selector('[data-test-subj=key-list-panel]').find(this.cssSelectorKey);
const notPatternedKeysNumber = await notPatternedKeys.count;
for (let i = 0; i < notPatternedKeysNumber; i++) {
await t.expect(notPatternedKeys.nth(i).withText(delimiter).exists).notOk('Not contained delimiter keys');
}
}
// Verify that every level of tree view is clickable
const foldersNumber = folders.length;
for (let i = 0; i < foldersNumber; i++) {
const innerFoldersNumber = folders[i].length;
const array: string[] = [];
for (let j = 0; j < innerFoldersNumber; j++) {
if (j === 0) {
const folderSelector = `[data-testid="node-item_${folders[i][j]}${delimiter}"]`;
array.push(folderSelector);
await t.click(Selector(folderSelector));
}
else {
const lastSelector = array[array.length - 1].substring(0, array[array.length - 1].length - 2);
const folderSelector = `${lastSelector}${folders[i][j]}${delimiter}"]`;
array.push(folderSelector);
await t.click(Selector(folderSelector));
}
}
// Verify that the last folder level contains required keys
const lastSelector = array[array.length - 1].substring(0, array[array.length - 1].length - 2);
const folderSelector = `${lastSelector}keys${delimiter}keys${delimiter}"]`;
await t.click(Selector(folderSelector));
const foundKeyName = `${folders[i].join(delimiter)}`;
await t
.expect(Selector(`[data-testid*="key-${foundKeyName}"]`).exists).ok('Specific key not found')
.click(array[0]);
}
}

/**
* Change delimiter value
* @delimiter string with delimiter value
*/
async changeDelimiterInTreeView(delimiter: string): Promise<void> {
// Open delimiter popup
await t.click(this.treeViewDelimiterButton);
// Apply new value to the field
await t.typeText(this.treeViewDelimiterInput, delimiter, { replace: true, paste: true });
// Click on save button
await t.click(this.treeViewDelimiterValueSave);
await t.expect(this.treeViewDelimiterButton.withExactText(delimiter).exists).ok('Delimiter is not changed');
}

//Delete entry from Stream key
async deleteStreamEntry(): Promise<void> {
Expand Down Expand Up @@ -1019,33 +951,6 @@ export class BrowserPage extends InstancePage {
.click(option);
}

/**
* Get text from first tree element
*/
async getTextFromNthTreeElement(number: number): Promise<string> {
return (await Selector('[role="treeitem"]').nth(number).find('div').textContent).replace(/\s/g, '');
}

/**
* Open tree folder with multiple level
* @param names folder names with sequence of subfolder
*/
async openTreeFolders(names: string[]): Promise<void> {
let base = `node-item_${names[0]}:`;
await t.click(Selector(`[data-testid="${base}"]`));
if (names.length > 1) {
for (let i = 1; i < names.length; i++) {
base = `${base }${names[i]}:`;
await t.click(Selector(`[data-testid="${base}"]`));
}
}
await t.click(Selector(`[data-testid="${base}keys:keys:"]`));

await t.expect(
Selector(`[data-testid="${base}keys:keys:"]`).visible)
.ok('Folder is not selected');
}

/**
* Verify that database has no keys
*/
Expand All @@ -1061,6 +966,10 @@ export class BrowserPage extends InstancePage {
await t.click(this.clearFilterButton);
}

/**
* Open Guide link by name
* @param guide The guide name
*/
async clickGuideLinksByName(guide: string): Promise<void> {
const linkGuide = Selector(`[data-testid="guide-button-${guide}"]`);
await t.click(linkGuide);
Expand Down
4 changes: 3 additions & 1 deletion tests/e2e/pageObjects/components/browser/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { BulkActions } from './bulk-actions';
import { TreeView } from './tree-view';

export {
BulkActions
BulkActions,
TreeView,
};
Loading