diff --git a/redisinsight/api/config/default.ts b/redisinsight/api/config/default.ts index 7346f1172f..10ba5e09c9 100644 --- a/redisinsight/api/config/default.ts +++ b/redisinsight/api/config/default.ts @@ -60,7 +60,7 @@ export default { tlsKey: process.env.SERVER_TLS_KEY, staticContent: !!process.env.SERVER_STATIC_CONTENT || false, buildType: process.env.BUILD_TYPE || 'ELECTRON', - appVersion: process.env.APP_VERSION || '2.36.0', + appVersion: process.env.APP_VERSION || '2.38.0', requestTimeout: parseInt(process.env.REQUEST_TIMEOUT, 10) || 25000, excludeRoutes: [], excludeAuthRoutes: [], diff --git a/redisinsight/api/config/swagger.ts b/redisinsight/api/config/swagger.ts index 22d24df01e..848273eb70 100644 --- a/redisinsight/api/config/swagger.ts +++ b/redisinsight/api/config/swagger.ts @@ -5,7 +5,7 @@ const SWAGGER_CONFIG: Omit = { info: { title: 'RedisInsight Backend API', description: 'RedisInsight Backend API', - version: '2.36.0', + version: '2.38.0', }, tags: [], }; diff --git a/redisinsight/api/package.json b/redisinsight/api/package.json index 633f3bb8e8..cab89a3019 100644 --- a/redisinsight/api/package.json +++ b/redisinsight/api/package.json @@ -1,6 +1,6 @@ { "name": "redisinsight-api", - "version": "2.36.0", + "version": "2.38.0", "description": "RedisInsight API", "private": true, "author": { @@ -42,7 +42,8 @@ "word-wrap": "1.2.4", "mocha/minimatch": "^3.0.5", "@nestjs/platform-socket.io/socket.io": "^4.7.1", - "**/semver": "^7.5.2" + "**/semver": "^7.5.2", + "winston-daily-rotate-file/**/file-stream-rotator": "^1.0.0" }, "dependencies": { "@nestjs/common": "^9.0.11", diff --git a/redisinsight/api/src/modules/browser/services/keys-business/scanner/strategies/standalone.strategy.spec.ts b/redisinsight/api/src/modules/browser/services/keys-business/scanner/strategies/standalone.strategy.spec.ts index 5ccc7785b0..694c79d57c 100644 --- a/redisinsight/api/src/modules/browser/services/keys-business/scanner/strategies/standalone.strategy.spec.ts +++ b/redisinsight/api/src/modules/browser/services/keys-business/scanner/strategies/standalone.strategy.spec.ts @@ -101,6 +101,40 @@ describe('Standalone Scanner Strategy', () => { null, ); }); + it('should scan 2000 items when count provided more then 2k', async () => { + const args = { ...getKeysDto, count: 10_000, match: '*' }; + jest.spyOn(Utils, 'getTotal').mockResolvedValue(mockGetTotalResponse_1); + + when(browserTool.execCommand) + .calledWith( + mockBrowserClientMetadata, + BrowserToolKeysCommands.Scan, + expect.anything(), + null, + ) + .mockResolvedValue([0, [getKeyInfoResponse.name]]); + + strategy.getKeysInfo = jest.fn().mockResolvedValue([getKeyInfoResponse]); + + const result = await strategy.getKeys(mockBrowserClientMetadata, args); + + expect(result).toEqual([ + { + ...mockNodeEmptyResult, + total: 1, + scanned: 2000, + keys: [getKeyInfoResponse], + }, + ]); + expect(strategy.getKeysInfo).toHaveBeenCalled(); + expect(browserTool.execCommand).toHaveBeenNthCalledWith( + 1, + mockBrowserClientMetadata, + BrowserToolKeysCommands.Scan, + ['0', 'MATCH', args.match, 'COUNT', 2000], + null, + ); + }); it('should return keys names and type only', async () => { const args = { ...getKeysDto, type: 'string', match: 'pattern*', keysInfo: false, diff --git a/redisinsight/api/src/modules/browser/services/keys-business/scanner/strategies/standalone.strategy.ts b/redisinsight/api/src/modules/browser/services/keys-business/scanner/strategies/standalone.strategy.ts index 79739907a5..ed98f915ac 100644 --- a/redisinsight/api/src/modules/browser/services/keys-business/scanner/strategies/standalone.strategy.ts +++ b/redisinsight/api/src/modules/browser/services/keys-business/scanner/strategies/standalone.strategy.ts @@ -86,6 +86,8 @@ export class StandaloneStrategy extends AbstractStrategy { count: number, type?: RedisDataType, ): Promise { + const COUNT = Math.min(2000, count); + let fullScanned = false; // todo: remove settings from here. threshold should be part of query? const settings = await this.settingsService.getAppSettings('1'); @@ -97,7 +99,7 @@ export class StandaloneStrategy extends AbstractStrategy { node.scanned < settings.scanThreshold ) ) { - let commandArgs = [`${node.cursor}`, 'MATCH', match, 'COUNT', count]; + let commandArgs = [`${node.cursor}`, 'MATCH', match, 'COUNT', COUNT]; if (type) { commandArgs = [...commandArgs, 'TYPE', type]; } @@ -112,7 +114,7 @@ export class StandaloneStrategy extends AbstractStrategy { // eslint-disable-next-line no-param-reassign node.cursor = parseInt(nextCursor, 10); // eslint-disable-next-line no-param-reassign - node.scanned += count; + node.scanned += COUNT; node.keys.push(...keys); fullScanned = node.cursor === 0; } diff --git a/redisinsight/api/yarn.lock b/redisinsight/api/yarn.lock index 2c28d8aed2..252ab1e1c7 100644 --- a/redisinsight/api/yarn.lock +++ b/redisinsight/api/yarn.lock @@ -3919,12 +3919,10 @@ file-entry-cache@^6.0.1: dependencies: flat-cache "^3.0.4" -file-stream-rotator@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/file-stream-rotator/-/file-stream-rotator-0.6.1.tgz#007019e735b262bb6c6f0197e58e5c87cb96cec3" - integrity sha512-u+dBid4PvZw17PmDeRcNOtCP9CCK/9lRN2w+r1xIS7yOL9JFrIBKTvrYsxT4P0pGtThYTn++QS5ChHaUov3+zQ== - dependencies: - moment "^2.29.1" +file-stream-rotator@^0.6.1, file-stream-rotator@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-stream-rotator/-/file-stream-rotator-1.0.0.tgz#de58379321a1ea6d2938ed5f5a2eff3b7f8b2780" + integrity sha512-qg5mQO7o+vhS7NPqkrkfJS8qqhz0d17Tnewmb5sUTUKwYe27LKaDtbTuRAtQWkBn6jROuFPVIDF5DtckzokFTQ== file-type@^16.5.4: version "16.5.4" @@ -6201,11 +6199,6 @@ mocha@^8.4.0: yargs-parser "20.2.4" yargs-unparser "2.0.0" -moment@^2.29.1: - version "2.29.4" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108" - integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w== - ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" diff --git a/redisinsight/desktop/src/lib/aboutPanel/aboutPanel.ts b/redisinsight/desktop/src/lib/aboutPanel/aboutPanel.ts index 922a8c18c2..392158b196 100644 --- a/redisinsight/desktop/src/lib/aboutPanel/aboutPanel.ts +++ b/redisinsight/desktop/src/lib/aboutPanel/aboutPanel.ts @@ -8,7 +8,7 @@ const ICON_PATH = app.isPackaged export const AboutPanelOptions = { applicationName: 'RedisInsight', - applicationVersion: `${app.getVersion() || '2.36.0'}${ + applicationVersion: `${app.getVersion() || '2.38.0'}${ !config.isProduction ? `-dev-${process.getCreationTime()}` : '' }`, copyright: `Copyright © ${new Date().getFullYear()} Redis Ltd.`, diff --git a/redisinsight/package.json b/redisinsight/package.json index 2ec250a74f..b595f5ceed 100644 --- a/redisinsight/package.json +++ b/redisinsight/package.json @@ -2,7 +2,7 @@ "name": "redisinsight", "productName": "RedisInsight", "private": true, - "version": "2.36.0", + "version": "2.38.0", "description": "RedisInsight", "main": "./dist/main/main.js", "author": { diff --git a/redisinsight/ui/src/pages/browser/modules/key-details/components/string-details/StringDetails.spec.tsx b/redisinsight/ui/src/pages/browser/modules/key-details/components/string-details/StringDetails.spec.tsx index dbe2cbaebf..2b50cd7536 100644 --- a/redisinsight/ui/src/pages/browser/modules/key-details/components/string-details/StringDetails.spec.tsx +++ b/redisinsight/ui/src/pages/browser/modules/key-details/components/string-details/StringDetails.spec.tsx @@ -1,7 +1,7 @@ import React from 'react' import { instance, mock } from 'ts-mockito' import { render, screen } from 'uiSrc/utils/test-utils' -import { stringDataSelector } from 'uiSrc/slices/browser/string' +import { stringDataSelector, stringSelector } from 'uiSrc/slices/browser/string' import { Props, StringDetails } from './StringDetails' const mockedProps = mock() @@ -15,6 +15,9 @@ jest.mock('uiSrc/slices/browser/string', () => ({ data: [49, 50, 51, 52], } }), + stringSelector: jest.fn().mockReturnValue({ + isCompressed: false + }) })) jest.mock('uiSrc/slices/browser/keys', () => ({ @@ -64,6 +67,22 @@ describe('StringDetails', () => { expect(editValueBtn).toHaveProperty('disabled', true) }) + it('should not be able to change value (compressed)', () => { + const stringSelectorMock = jest.fn().mockReturnValue({ + isCompressed: true + }) + stringSelector.mockImplementation(stringSelectorMock) + + render( + + ) + + const editValueBtn = screen.getByTestId(`${EDIT_VALUE_BTN_TEST_ID}`) + expect(editValueBtn).toHaveProperty('disabled', true) + }) + it('"edit-key-value-btn" should render', () => { const { queryByTestId } = render() expect(queryByTestId('edit-key-value-btn')).toBeInTheDocument() diff --git a/redisinsight/ui/src/pages/browser/modules/key-details/components/string-details/StringDetails.tsx b/redisinsight/ui/src/pages/browser/modules/key-details/components/string-details/StringDetails.tsx index bea335540b..279614065c 100644 --- a/redisinsight/ui/src/pages/browser/modules/key-details/components/string-details/StringDetails.tsx +++ b/redisinsight/ui/src/pages/browser/modules/key-details/components/string-details/StringDetails.tsx @@ -56,7 +56,7 @@ const StringDetails = (props: Props) => { setEditItem(!editItem)} /> ) diff --git a/redisinsight/ui/src/pages/browser/modules/key-details/components/string-details/string-details-table/StringDetailsTable.tsx b/redisinsight/ui/src/pages/browser/modules/key-details/components/string-details/string-details-table/StringDetailsTable.tsx index cd92f6115b..00b0b102ee 100644 --- a/redisinsight/ui/src/pages/browser/modules/key-details/components/string-details/string-details-table/StringDetailsTable.tsx +++ b/redisinsight/ui/src/pages/browser/modules/key-details/components/string-details/string-details-table/StringDetailsTable.tsx @@ -51,8 +51,7 @@ import { IFetchKeyArgs } from 'uiSrc/constants/prop-types/keys' import styles from './styles.module.scss' -const MAX_ROWS = 25 -const MIN_ROWS = 4 +const MIN_ROWS = 8 const APPROXIMATE_WIDTH_OF_SIGN = 8.6 const MAX_LENGTH = STRING_MAX_LENGTH + 1 @@ -72,7 +71,7 @@ const StringDetailsTable = (props: Props) => { const { name: key, type: keyType, length } = useSelector(selectedKeyDataSelector) ?? { name: '' } const { viewFormat: viewFormatProp } = useSelector(selectedKeySelector) - const [rows, setRows] = useState(5) + const [rows, setRows] = useState(MIN_ROWS) const [value, setValue] = useState('') const [areaValue, setAreaValue] = useState('') const [viewFormat, setViewFormat] = useState(viewFormatProp) @@ -83,6 +82,7 @@ const StringDetailsTable = (props: Props) => { const textAreaRef: Ref = useRef(null) const viewValueRef: Ref = useRef(null) + const containerRef: Ref = useRef(null) const dispatch = useDispatch() @@ -125,16 +125,9 @@ const StringDetailsTable = (props: Props) => { return } const calculatedRows = calculateTextareaLines(areaValue, textAreaRef.current.clientWidth, APPROXIMATE_WIDTH_OF_SIGN) - - if (calculatedRows > MAX_ROWS) { - setRows(MAX_ROWS) - return + if (calculatedRows > MIN_ROWS) { + setRows(calculatedRows) } - if (calculatedRows < MIN_ROWS) { - setRows(MIN_ROWS) - return - } - setRows(calculatedRows) }, [viewValueRef, isEditItem]) useMemo(() => { @@ -188,7 +181,7 @@ const StringDetailsTable = (props: Props) => { return ( <> -
+
{isLoading && ( { /> )} {!isEditItem && ( - isEditable && setIsEdit(true)} - style={{ whiteSpace: 'break-spaces' }} - data-testid="string-value" + - {areaValue !== '' - ? (isValid + isEditable && setIsEdit(true)} + style={{ whiteSpace: 'break-spaces' }} + data-testid="string-value" + > + {areaValue !== '' ? value - : ( - - <>{value} - - ) - ) - : (!isLoading && (Empty))} - + : (!isLoading && (Empty))} + + )} {isEditItem && ( { disabled={loading} inputRef={textAreaRef} className={cx(styles.stringTextArea, { [styles.areaWarning]: isDisabled })} + style={{ maxHeight: containerRef.current ? containerRef.current?.clientHeight - 80 : '100%' }} data-testid="string-value" /> diff --git a/redisinsight/ui/src/pages/browser/modules/key-details/components/string-details/string-details-table/styles.module.scss b/redisinsight/ui/src/pages/browser/modules/key-details/components/string-details/string-details-table/styles.module.scss index 3ae9881baf..764fa4e7d7 100644 --- a/redisinsight/ui/src/pages/browser/modules/key-details/components/string-details/string-details-table/styles.module.scss +++ b/redisinsight/ui/src/pages/browser/modules/key-details/components/string-details/string-details-table/styles.module.scss @@ -6,14 +6,10 @@ $outer-height: 220px; $outer-height-mobile: 340px; .container { - @include euiScrollBar; padding: 20px 16px 20px; - max-height: calc(100vh - #{$outer-height}); - overflow-y: auto; - overflow-x: hidden; - word-break: break-word; + overflow: hidden; color: var(--euiTextSubduedColor); flex: 1; position: relative; @@ -29,10 +25,12 @@ $outer-height-mobile: 340px; } .stringValue { - font: inherit !important; - color: inherit !important; - padding: 0 !important; - background: inherit !important; + @include euiScrollBar; + overflow-y: auto; + overflow-x: hidden; + word-break: break-word; + line-height: 1.2; + width: 100%; pre { background-color: transparent !important; @@ -41,17 +39,19 @@ $outer-height-mobile: 340px; } .stringTextArea { - max-height: calc(100vh - #{$outer-height} - 55px); - @media only screen and (max-width: 767px) { - max-height: calc(100vh - #{$outer-height-mobile} - 55px); - } - &.areaWarning { border-color: var(--euiColorWarningLight) !important; background-image: none !important; } } +.tooltipAnchor { + display: inline-flex !important; + height: auto; + max-height: 100%; + width: 100%; +} + .stringFooterBtn { &:global(.euiButton) { color: var(--euiTextSubduedColor) !important; diff --git a/redisinsight/ui/src/utils/comparisons/diff.ts b/redisinsight/ui/src/utils/comparisons/diff.ts index 5f7fcc4736..b154ed3a47 100644 --- a/redisinsight/ui/src/utils/comparisons/diff.ts +++ b/redisinsight/ui/src/utils/comparisons/diff.ts @@ -23,7 +23,7 @@ export const getFormUpdates = (obj1: UnknownObject = {}, obj2: UnknownObject = { obj1, (result: UnknownObject, value, key) => { if (isObject(value)) { - const diff = getFormUpdates(value, obj2[key]) + const diff = getFormUpdates(value, obj2[key] || {}) if (Object.keys(diff).length) { result[key] = diff diff --git a/tests/e2e/common-actions/workbench-actions.ts b/tests/e2e/common-actions/workbench-actions.ts index 4d495c1102..14242166b8 100644 --- a/tests/e2e/common-actions/workbench-actions.ts +++ b/tests/e2e/common-actions/workbench-actions.ts @@ -1,4 +1,4 @@ -import {t, Selector} from 'testcafe'; +import { t, Selector } from 'testcafe'; import { WorkbenchPage } from '../pageObjects'; const workbenchPage = new WorkbenchPage(); diff --git a/tests/e2e/desktop.runner.ts b/tests/e2e/desktop.runner.ts index c2081947e6..15effadce6 100644 --- a/tests/e2e/desktop.runner.ts +++ b/tests/e2e/desktop.runner.ts @@ -6,16 +6,16 @@ import testcafe from 'testcafe'; return t .createRunner() .compilerOptions({ - "typescript": { + 'typescript': { configPath: 'tsconfig.testcafe.json', experimentalDecorators: true - }}) + } }) .src((process.env.TEST_FILES || 'tests/electron/**/*.e2e.ts').split('\n')) .browsers(['electron']) .screenshots({ path: './report/screenshots/', takeOnFails: true, - pathPattern: '${USERAGENT}/${DATE}_${TIME}/${FIXTURE}_${TEST}_${FILE_INDEX}.png', + pathPattern: '${USERAGENT}/${DATE}_${TIME}/${FIXTURE}_${TEST}_${FILE_INDEX}.png' }) .reporter([ 'spec', @@ -46,7 +46,7 @@ import testcafe from 'testcafe'; process.exit(failedCount); }) .catch((e) => { - console.error(e) + console.error(e); process.exit(1); }); })(); diff --git a/tests/e2e/desktop.runner.win.ts b/tests/e2e/desktop.runner.win.ts index 17de2317e2..edb738b2a0 100644 --- a/tests/e2e/desktop.runner.win.ts +++ b/tests/e2e/desktop.runner.win.ts @@ -6,16 +6,16 @@ import testcafe from 'testcafe'; return t .createRunner() .compilerOptions({ - "typescript": { + 'typescript': { configPath: 'tsconfig.testcafe.json', experimentalDecorators: true - }}) + } }) .src((process.env.TEST_FILES || 'tests/electron/**/*.e2e.ts').split('\n')) .browsers(['electron']) .screenshots({ path: 'report/screenshots/', takeOnFails: true, - pathPattern: '${USERAGENT}/${DATE}_${TIME}/${FIXTURE}_${TEST}_${FILE_INDEX}.png', + pathPattern: '${USERAGENT}/${DATE}_${TIME}/${FIXTURE}_${TEST}_${FILE_INDEX}.png' }) .reporter([ 'spec', diff --git a/tests/e2e/helpers/api/api-database.ts b/tests/e2e/helpers/api/api-database.ts index e91051b7ea..c77262f827 100644 --- a/tests/e2e/helpers/api/api-database.ts +++ b/tests/e2e/helpers/api/api-database.ts @@ -27,28 +27,28 @@ export class DatabaseAPIRequests { ): Promise { const uniqueId = chance.string({ length: 10 }); const requestBody: { - name?: string; - host: string; - port: number; - username?: string; - password?: string; - tls?: boolean; - verifyServerCert?: boolean; + name?: string, + host: string, + port: number, + username?: string, + password?: string, + tls?: boolean, + verifyServerCert?: boolean, caCert?: { - name: string; - certificate?: string; - }; + name: string, + certificate?: string + }, clientCert?: { - name: string; - certificate?: string; - key?: string; - }; + name: string, + certificate?: string, + key?: string + } } = { name: databaseParameters.databaseName, host: databaseParameters.host, port: Number(databaseParameters.port), username: databaseParameters.databaseUsername, - password: databaseParameters.databasePassword, + password: databaseParameters.databasePassword }; if (databaseParameters.caCert) { diff --git a/tests/e2e/helpers/api/api-info.ts b/tests/e2e/helpers/api/api-info.ts index 7d41fdbd7f..978b0e9629 100644 --- a/tests/e2e/helpers/api/api-info.ts +++ b/tests/e2e/helpers/api/api-info.ts @@ -1,6 +1,6 @@ import { t } from 'testcafe'; -import { sendPostRequest } from './api-common'; import { ResourcePath } from '../constants'; +import { sendPostRequest } from './api-common'; /** * Synchronize features diff --git a/tests/e2e/helpers/common.ts b/tests/e2e/helpers/common.ts index 4505f631dc..9fcbd4a171 100644 --- a/tests/e2e/helpers/common.ts +++ b/tests/e2e/helpers/common.ts @@ -1,6 +1,6 @@ import * as path from 'path'; -import * as archiver from 'archiver'; import * as fs from 'fs'; +import * as archiver from 'archiver'; import { ClientFunction, RequestMock, t } from 'testcafe'; import { Chance } from 'chance'; import { apiUrl, commonUrl } from './conf'; @@ -13,7 +13,6 @@ declare global { } } - const settingsApiUrl = `${commonUrl}/api/settings`; process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; // lgtm[js/disabling-certificate-validation] const mockedSettingsResponse = { diff --git a/tests/e2e/helpers/database-scripts.ts b/tests/e2e/helpers/database-scripts.ts index 9bc7ff95a9..faba4a431d 100644 --- a/tests/e2e/helpers/database-scripts.ts +++ b/tests/e2e/helpers/database-scripts.ts @@ -1,5 +1,5 @@ -import { workingDirectory } from '../helpers/conf'; import * as sqlite3 from 'sqlite3'; +import { workingDirectory } from '../helpers/conf'; const dbPath = `${workingDirectory}/redisinsight.db`; @@ -17,7 +17,8 @@ export async function updateColumnValueInDBTable(tableName: string, columnName: db.run(query, (err: { message: string }) => { if (err) { reject(new Error(`Error during changing ${columnName} column value: ${err.message}`)); - } else { + } + else { db.close(); resolve(); } @@ -38,7 +39,8 @@ export async function getColumnValueFromTableInDB(tableName: string, columnName: db.get(query, (err: { message: string }, row: any) => { if (err) { reject(new Error(`Error during getting ${columnName} column value: ${err.message}`)); - } else { + } + else { const columnValue = row[columnName]; db.close(); resolve(columnValue); @@ -57,11 +59,11 @@ export async function deleteRowsFromTableInDB(tableName: string): Promise return new Promise((resolve, reject) => { - db.run(query, (err: { message: string }) => { if (err) { reject(new Error(`Error during ${tableName} table rows deletion: ${err.message}`)); - } else { + } + else { db.close(); resolve(); } diff --git a/tests/e2e/helpers/insights.ts b/tests/e2e/helpers/insights.ts index 6a3709d83b..240dedf2bf 100644 --- a/tests/e2e/helpers/insights.ts +++ b/tests/e2e/helpers/insights.ts @@ -1,5 +1,5 @@ -import * as fs from 'fs-extra'; import * as path from 'path'; +import * as fs from 'fs-extra'; import { BasePage } from '../pageObjects'; import { deleteRowsFromTableInDB, updateColumnValueInDBTable } from './database-scripts'; import { syncFeaturesApi } from './api/api-info'; diff --git a/tests/e2e/helpers/notifications.ts b/tests/e2e/helpers/notifications.ts index ad17268074..b619b350ce 100644 --- a/tests/e2e/helpers/notifications.ts +++ b/tests/e2e/helpers/notifications.ts @@ -1,4 +1,4 @@ -import { workingDirectory} from '../helpers/conf'; +import { workingDirectory } from '../helpers/conf'; import { NotificationParameters } from '../pageObjects/components/navigation/notification-panel'; const dbPath = `${workingDirectory}/redisinsight.db`; diff --git a/tests/e2e/pageObjects/browser-page.ts b/tests/e2e/pageObjects/browser-page.ts index 98787eb7bf..8d698561df 100644 --- a/tests/e2e/pageObjects/browser-page.ts +++ b/tests/e2e/pageObjects/browser-page.ts @@ -39,7 +39,7 @@ export class BrowserPage extends InstancePage { refreshKeysButton = Selector('[data-testid=refresh-keys-btn]'); refreshKeyButton = Selector('[data-testid=refresh-key-btn]'); editKeyNameButton = Selector('[data-testid=edit-key-btn]'); - editKeyValueButton = Selector('[data-testid=edit-key-value-btn]'); + editKeyValueButton = Selector('[data-testid=edit-key-value-btn]', { timeout: 500 }); closeKeyButton = Selector('[data-testid=close-key-btn]'); plusAddKeyButton = Selector('[data-testid=btn-add-key]'); addKeyValueItemsButton = Selector('[data-testid=add-key-value-items-btn]'); diff --git a/tests/e2e/pageObjects/components/browser/index.ts b/tests/e2e/pageObjects/components/browser/index.ts index 79bba1bb76..d61d98397b 100644 --- a/tests/e2e/pageObjects/components/browser/index.ts +++ b/tests/e2e/pageObjects/components/browser/index.ts @@ -3,5 +3,5 @@ import { TreeView } from './tree-view'; export { BulkActions, - TreeView, + TreeView }; diff --git a/tests/e2e/pageObjects/components/myRedisDatabase/add-redis-database.ts b/tests/e2e/pageObjects/components/myRedisDatabase/add-redis-database.ts index 1c540c794e..104ba0dc9b 100644 --- a/tests/e2e/pageObjects/components/myRedisDatabase/add-redis-database.ts +++ b/tests/e2e/pageObjects/components/myRedisDatabase/add-redis-database.ts @@ -266,9 +266,8 @@ export class AddRedisDatabase { /** * set copressor value in dropdown * @param compressor - compressor value - * @param value - checkbox value */ - async setCompressorValue(compressor: string){ + async setCompressorValue(compressor: string): Promise { if(!await this.selectCompressor.exists) { await t.click(this.dataCompressorLabel); diff --git a/tests/e2e/pageObjects/index.ts b/tests/e2e/pageObjects/index.ts index 855275febb..5d62c57a5c 100644 --- a/tests/e2e/pageObjects/index.ts +++ b/tests/e2e/pageObjects/index.ts @@ -27,5 +27,5 @@ export { InstancePage, TriggersAndFunctionsLibrariesPage, TriggersAndFunctionsFunctionsPage, - WelcomePage, + WelcomePage }; diff --git a/tests/e2e/pageObjects/workbench-page.ts b/tests/e2e/pageObjects/workbench-page.ts index c94303a85d..d04303adc6 100644 --- a/tests/e2e/pageObjects/workbench-page.ts +++ b/tests/e2e/pageObjects/workbench-page.ts @@ -290,6 +290,6 @@ export class WorkbenchPage extends InstancePage { do { imageHeight = await selector.getStyleProperty('height'); } - while ((imageHeight == '0px') && Date.now() - startTime < searchTimeout); + while ((imageHeight === '0px') && Date.now() - startTime < searchTimeout); } } diff --git a/tests/e2e/tests/web/critical-path/browser/formatters.e2e.ts b/tests/e2e/tests/web/critical-path/browser/formatters.e2e.ts index d39ca364e1..89ca3e7946 100644 --- a/tests/e2e/tests/web/critical-path/browser/formatters.e2e.ts +++ b/tests/e2e/tests/web/critical-path/browser/formatters.e2e.ts @@ -57,11 +57,11 @@ formattersHighlightedSet.forEach(formatter => { // Verify that value is formatted and highlighted await t.expect(valueSelector.find(browserPage.cssJsonValue).exists).ok(`${key.textType} Value is not formatted to ${formatter.format}`); // Verify that Hash field is formatted and highlighted for JSON and PHP serialized - if (key.keyName === 'hash') { + if (key.textType === 'Hash') { await t.expect(browserPage.hashField.find(browserPage.cssJsonValue).exists).ok(`Hash field is not formatted to ${formatter.format}`); } // Verify that Stream field is formatted and highlighted for JSON and PHP serialized - if (key.keyName === 'stream') { + if (key.textType === 'Stream') { await t.expect(Selector(browserPage.cssJsonValue).count).eql(2, `Hash field is not formatted to ${formatter.format}`); } } @@ -193,10 +193,10 @@ notEditableFormattersSet.forEach(formatter => { // Verify for Protobuf, Java serialized, Pickle // Verify for Hash, List, ZSet, String keys for (const key of keysData) { - if (key.keyName === 'hash' || key.keyName === 'list' || key.keyName === 'zset' || key.keyName === 'string') { - const editBtn = (key.keyName === 'string') + if (key.textType === 'Hash' || key.textType === 'List' || key.textType === 'String') { + const editBtn = (key.textType === 'String') ? browserPage.editKeyValueButton - : Selector(`[data-testid^=edit-][data-testid*=${key.keyName.split('-')[0]}]`); + : Selector(`[data-testid*=edit-][data-testid*=${key.keyName.split('-')[0]}]`, { timeout: 500 }); await browserPage.openKeyDetailsByKeyName(key.keyName); await browserPage.selectFormatter(formatter.format); // Verify that edit button disabled @@ -206,6 +206,13 @@ notEditableFormattersSet.forEach(formatter => { // Verify tooltip content await t.expect(browserPage.tooltip.textContent).contains('Cannot edit the value in this format', 'Tooltip has wrong text'); } + if (key.textType === 'Sorted Set') { + const editBtn = Selector(`[data-testid*=edit-][data-testid*=${key.keyName.split('-')[0]}]`, { timeout: 500 }); + await browserPage.openKeyDetailsByKeyName(key.keyName); + await browserPage.selectFormatter(formatter.format); + // Verify that edit button enabled for ZSet + await t.expect(editBtn.hasAttribute('disabled')).notOk(`Key ${key.textType} is disabled for ${formatter.format} formatter`); + } } }); }); diff --git a/tests/e2e/tests/web/critical-path/browser/scan-keys.e2e.ts b/tests/e2e/tests/web/critical-path/browser/scan-keys.e2e.ts index 3d51c36c0c..286b01f8ee 100644 --- a/tests/e2e/tests/web/critical-path/browser/scan-keys.e2e.ts +++ b/tests/e2e/tests/web/critical-path/browser/scan-keys.e2e.ts @@ -32,7 +32,10 @@ fixture `Browser - Specify Keys to Scan` .beforeEach(async() => { await databaseHelper.acceptLicenseTermsAndAddDatabaseApi(ossStandaloneConfig); }) - .afterEach(async() => { + .afterEach(async t => { + await t.click(myRedisDatabasePage.NavigationPanel.settingsButton); + await t.click(settingsPage.accordionAdvancedSettings); + await settingsPage.changeKeysToScanValue('10000'); //Clear and delete database await browserPage.Cli.sendCommandInCli(`DEL ${keys.join(' ')}`); await databaseAPIRequests.deleteStandaloneDatabaseApi(ossStandaloneConfig); diff --git a/tests/e2e/tests/web/critical-path/database-overview/database-index.e2e.ts b/tests/e2e/tests/web/critical-path/database-overview/database-index.e2e.ts index 10cd1d4f2d..7f2e706480 100644 --- a/tests/e2e/tests/web/critical-path/database-overview/database-index.e2e.ts +++ b/tests/e2e/tests/web/critical-path/database-overview/database-index.e2e.ts @@ -48,7 +48,7 @@ fixture `Allow to change database index` }); test('Switching between indexed databases', async t => { const command = `HSET ${logicalDbKey} "name" "Gillford School" "description" "Gillford School is a centre" "class" "private" "type" "democratic; waldorf" "address_city" "Goudhurst" "address_street" "Goudhurst" "students" 721 "location" "51.112685, 0.451076"`; - const rememberedConnectedClients = await browserPage.overviewConnectedClients.textContent; + // const rememberedConnectedClients = await browserPage.overviewConnectedClients.textContent; // Change index to logical db // Verify that database index switcher displayed for Standalone db diff --git a/tests/e2e/tests/web/critical-path/database-overview/database-overview.e2e.ts b/tests/e2e/tests/web/critical-path/database-overview/database-overview.e2e.ts index b6bd6cb85f..1a8941ae09 100644 --- a/tests/e2e/tests/web/critical-path/database-overview/database-overview.e2e.ts +++ b/tests/e2e/tests/web/critical-path/database-overview/database-overview.e2e.ts @@ -16,7 +16,6 @@ import { } from '../../../../helpers/conf'; import { DatabaseAPIRequests } from '../../../../helpers/api/api-database'; - const myRedisDatabasePage = new MyRedisDatabasePage(); const browserPage = new BrowserPage(); const chance = new Chance(); @@ -47,8 +46,8 @@ test await databaseAPIRequests.deleteStandaloneDatabaseApi(ossStandaloneConfig); await databaseAPIRequests.deleteStandaloneDatabaseApi(ossStandaloneRedisearch); })('Verify that user can see the list of Modules updated each time when he connects to the database', async t => { - let firstDatabaseModules: string[] = []; - let secondDatabaseModules: string[] = []; + const firstDatabaseModules: string[] = []; + const secondDatabaseModules: string[] = []; //Remember modules await t.click(browserPage.OverviewPanel.overviewMoreInfo); const moduleIcons = Selector('div').find('[data-testid^=Redi]'); diff --git a/tests/e2e/tests/web/critical-path/database/import-databases.e2e.ts b/tests/e2e/tests/web/critical-path/database/import-databases.e2e.ts index 4ac60774e9..971fa8f00b 100644 --- a/tests/e2e/tests/web/critical-path/database/import-databases.e2e.ts +++ b/tests/e2e/tests/web/critical-path/database/import-databases.e2e.ts @@ -233,7 +233,7 @@ test('Certificates import with/without path', async t => { }); test('Import SSH parameters', async t => { const sshAgentsResult = 'SSH Agents are not supported'; - const sshPrivateKey = '-----BEGIN OPENSSH PRIVATE KEY-----'; + // const sshPrivateKey = '-----BEGIN OPENSSH PRIVATE KEY-----'; await databasesActions.importDatabase(racompSSHData); // Fully imported table with SSH diff --git a/tests/e2e/tests/web/critical-path/memory-efficiency/recommendations.e2e.ts b/tests/e2e/tests/web/critical-path/memory-efficiency/recommendations.e2e.ts index 776c4a7daf..87ff75a84d 100644 --- a/tests/e2e/tests/web/critical-path/memory-efficiency/recommendations.e2e.ts +++ b/tests/e2e/tests/web/critical-path/memory-efficiency/recommendations.e2e.ts @@ -39,7 +39,7 @@ fixture `Memory Efficiency Recommendations` // Go to Analysis Tools page await t.click(myRedisDatabasePage.NavigationPanel.analysisPageButton); }) - .afterEach(async t => { + .afterEach(async() => { // Clear and delete database await apiKeyRequests.deleteKeyByNameApi(keyName, ossStandaloneConfig.databaseName); await databaseAPIRequests.deleteStandaloneDatabaseApi(ossStandaloneConfig); @@ -174,7 +174,7 @@ test.skip // Go to Recommendations tab await t.click(memoryEfficiencyPage.recommendationsTab); }) - .after(async t => { + .after(async() => { // Clear and delete database await apiKeyRequests.deleteKeyByNameApi(keyName, ossStandaloneConfig.databaseName); await databaseAPIRequests.deleteStandaloneDatabaseApi(ossStandaloneConfig); diff --git a/tests/e2e/tests/web/critical-path/memory-efficiency/top-keys-table.e2e.ts b/tests/e2e/tests/web/critical-path/memory-efficiency/top-keys-table.e2e.ts index 9e417e3ebe..d902c93ba3 100644 --- a/tests/e2e/tests/web/critical-path/memory-efficiency/top-keys-table.e2e.ts +++ b/tests/e2e/tests/web/critical-path/memory-efficiency/top-keys-table.e2e.ts @@ -3,7 +3,7 @@ import { Selector } from 'testcafe'; import { MyRedisDatabasePage, MemoryEfficiencyPage, BrowserPage } from '../../../../pageObjects'; import { rte } from '../../../../helpers/constants'; import { DatabaseHelper } from '../../../../helpers/database'; -import { commonUrl, ossStandaloneConfig, ossStandaloneRedisearch } from '../../../../helpers/conf'; +import { commonUrl, ossStandaloneRedisearch } from '../../../../helpers/conf'; import { DatabaseAPIRequests } from '../../../../helpers/api/api-database'; import { deleteAllKeysFromDB, populateDBWithHashes, populateHashWithFields } from '../../../../helpers/keys'; import { Common } from '../../../../helpers/common'; @@ -80,7 +80,7 @@ test // Go to Analysis Tools page await t.click(myRedisDatabasePage.NavigationPanel.analysisPageButton); }) - .after(async t => { + .after(async() => { await apiKeyRequests.deleteKeyByNameApi(keyName, ossStandaloneRedisearch.databaseName); await databaseAPIRequests.deleteStandaloneDatabaseApi(ossStandaloneRedisearch); })('Big highlighted key tooltip', async t => { diff --git a/tests/e2e/tests/web/critical-path/settings/settings.e2e.ts b/tests/e2e/tests/web/critical-path/settings/settings.e2e.ts index fcc26fdc21..f69c7fbcc0 100644 --- a/tests/e2e/tests/web/critical-path/settings/settings.e2e.ts +++ b/tests/e2e/tests/web/critical-path/settings/settings.e2e.ts @@ -21,6 +21,9 @@ fixture `Settings` .clientScripts({ content: `(${explicitErrorHandler.toString()})()` }) .beforeEach(async() => { await databaseHelper.acceptLicenseTerms(); + }) + .afterEach(async() => { + await settingsPage.changeKeysToScanValue('10000'); }); test('Verify that user can customize a number of keys to scan in filters per key name or key type', async t => { // Go to Settings page diff --git a/tests/e2e/tests/web/critical-path/workbench/cypher.e2e.ts b/tests/e2e/tests/web/critical-path/workbench/cypher.e2e.ts index 288c300b0c..f7db81f308 100644 --- a/tests/e2e/tests/web/critical-path/workbench/cypher.e2e.ts +++ b/tests/e2e/tests/web/critical-path/workbench/cypher.e2e.ts @@ -10,7 +10,7 @@ const databaseHelper = new DatabaseHelper(); const databaseAPIRequests = new DatabaseAPIRequests(); fixture `Cypher syntax at Workbench` - .meta({type: 'critical_path', rte: rte.standalone}) + .meta({ type: 'critical_path', rte: rte.standalone }) .page(commonUrl) .beforeEach(async t => { await databaseHelper.acceptLicenseTermsAndAddDatabaseApi(ossStandaloneConfig); diff --git a/tests/e2e/tests/web/critical-path/workbench/default-scripts-area.e2e.ts b/tests/e2e/tests/web/critical-path/workbench/default-scripts-area.e2e.ts index 271e86e35c..64d8ef1723 100644 --- a/tests/e2e/tests/web/critical-path/workbench/default-scripts-area.e2e.ts +++ b/tests/e2e/tests/web/critical-path/workbench/default-scripts-area.e2e.ts @@ -24,7 +24,7 @@ const expectedProperties = [ ]; fixture `Default scripts area at Workbench` - .meta({type: 'critical_path', rte: rte.standalone}) + .meta({ type: 'critical_path', rte: rte.standalone }) .page(commonUrl) .beforeEach(async t => { await databaseHelper.acceptLicenseTermsAndAddDatabaseApi(ossStandaloneRedisearch); diff --git a/tests/e2e/tests/web/regression/browser/add-keys.e2e.ts b/tests/e2e/tests/web/regression/browser/add-keys.e2e.ts index 4da14a05ab..318bbcd677 100644 --- a/tests/e2e/tests/web/regression/browser/add-keys.e2e.ts +++ b/tests/e2e/tests/web/regression/browser/add-keys.e2e.ts @@ -5,7 +5,6 @@ import { commonUrl, ossStandaloneBigConfig, ossStandaloneConfig } from '../../.. import { DatabaseAPIRequests } from '../../../../helpers/api/api-database'; import { Common } from '../../../../helpers/common'; import { BrowserActions } from '../../../../common-actions/browser-actions'; -import { verifyKeysDisplayingInTheList } from '../../../../helpers/keys'; const browserPage = new BrowserPage(); const browserActions = new BrowserActions(); diff --git a/tests/e2e/tests/web/regression/browser/resize-columns.e2e.ts b/tests/e2e/tests/web/regression/browser/resize-columns.e2e.ts index 9f1e3e946f..5f86ecff1c 100644 --- a/tests/e2e/tests/web/regression/browser/resize-columns.e2e.ts +++ b/tests/e2e/tests/web/regression/browser/resize-columns.e2e.ts @@ -7,7 +7,6 @@ import { rte } from '../../../../helpers/constants'; import { commonUrl, ossStandaloneConfig } from '../../../../helpers/conf'; import { DatabaseAPIRequests } from '../../../../helpers/api/api-database'; import { Common } from '../../../../helpers/common'; -import { t } from 'testcafe'; const myRedisDatabasePage = new MyRedisDatabasePage(); const browserPage = new BrowserPage(); diff --git a/tests/e2e/tests/web/regression/browser/scan-keys.e2e.ts b/tests/e2e/tests/web/regression/browser/scan-keys.e2e.ts index 647e1195f4..4dea83f750 100644 --- a/tests/e2e/tests/web/regression/browser/scan-keys.e2e.ts +++ b/tests/e2e/tests/web/regression/browser/scan-keys.e2e.ts @@ -16,11 +16,14 @@ const explicitErrorHandler = (): void => { }; fixture `Browser - Specify Keys to Scan` - .meta({type: 'regression', rte: rte.none}) + .meta({ type: 'regression', rte: rte.none }) .page(commonUrl) .clientScripts({ content: `(${explicitErrorHandler.toString()})()` }) .beforeEach(async() => { await databaseHelper.acceptLicenseTerms(); + }) + .afterEach(async() => { + await settingsPage.changeKeysToScanValue('10000'); }); test('Verify that the user not enter the value less than 500 - the system automatically applies min value if user enters less than min', async t => { // Go to Settings page diff --git a/tests/e2e/tests/web/regression/workbench/autocomplete.e2e.ts b/tests/e2e/tests/web/regression/workbench/autocomplete.e2e.ts index 2a1f478576..12a7de4b41 100644 --- a/tests/e2e/tests/web/regression/workbench/autocomplete.e2e.ts +++ b/tests/e2e/tests/web/regression/workbench/autocomplete.e2e.ts @@ -10,7 +10,7 @@ const databaseHelper = new DatabaseHelper(); const databaseAPIRequests = new DatabaseAPIRequests(); fixture `Autocomplete for entered commands` - .meta({type: 'regression', rte: rte.standalone}) + .meta({ type: 'regression', rte: rte.standalone }) .page(commonUrl) .beforeEach(async t => { await databaseHelper.acceptLicenseTermsAndAddDatabaseApi(ossStandaloneConfig); diff --git a/tests/e2e/tests/web/regression/workbench/context.e2e.ts b/tests/e2e/tests/web/regression/workbench/context.e2e.ts index 224070a4b9..3aded27a14 100644 --- a/tests/e2e/tests/web/regression/workbench/context.e2e.ts +++ b/tests/e2e/tests/web/regression/workbench/context.e2e.ts @@ -50,7 +50,7 @@ test('Verify that user can see saved CLI size when navigates away to any other p test('Verify that user can see all the information removed when reloads the page', async t => { const command = 'FT._LIST'; // Create context modificaions and navigate to Browser - await t.typeText(workbenchPage.queryInput, command, { replace: true, speed: speed}); + await t.typeText(workbenchPage.queryInput, command, { replace: true, speed: speed }); await t.click(workbenchPage.Cli.cliExpandButton); await t.click(myRedisDatabasePage.NavigationPanel.browserButton); // Open Workbench page and verify context diff --git a/tests/e2e/tests/web/regression/workbench/cypher.e2e.ts b/tests/e2e/tests/web/regression/workbench/cypher.e2e.ts index e65ff793b2..be706fb127 100644 --- a/tests/e2e/tests/web/regression/workbench/cypher.e2e.ts +++ b/tests/e2e/tests/web/regression/workbench/cypher.e2e.ts @@ -12,7 +12,7 @@ const databaseAPIRequests = new DatabaseAPIRequests(); const command = 'GRAPH.QUERY graph'; fixture `Cypher syntax at Workbench` - .meta({type: 'regression', rte: rte.standalone}) + .meta({ type: 'regression', rte: rte.standalone }) .page(commonUrl) .beforeEach(async t => { await databaseHelper.acceptLicenseTermsAndAddDatabaseApi(ossStandaloneConfig); diff --git a/tests/e2e/tests/web/regression/workbench/default-scripts-area.e2e.ts b/tests/e2e/tests/web/regression/workbench/default-scripts-area.e2e.ts index c523cf3af4..e0ee1990d4 100644 --- a/tests/e2e/tests/web/regression/workbench/default-scripts-area.e2e.ts +++ b/tests/e2e/tests/web/regression/workbench/default-scripts-area.e2e.ts @@ -10,7 +10,7 @@ const databaseHelper = new DatabaseHelper(); const databaseAPIRequests = new DatabaseAPIRequests(); fixture `Default scripts area at Workbench` - .meta({type: 'regression', rte: rte.standalone}) + .meta({ type: 'regression', rte: rte.standalone }) .page(commonUrl) .beforeEach(async t => { await databaseHelper.acceptLicenseTermsAndAddDatabaseApi(ossStandaloneConfig); @@ -20,132 +20,132 @@ fixture `Default scripts area at Workbench` .afterEach(async() => { // Delete database await databaseAPIRequests.deleteStandaloneDatabaseApi(ossStandaloneConfig); - }) -test('Verify that user can expand/collapse the enablement area', async t => { - // Hover over Enablement area - await t.hover(workbenchPage.preselectArea); - // Collapse the area with default scripts - await t.click(workbenchPage.collapsePreselectAreaButton); - // Validate that Enablement area is not displayed - await t.expect(workbenchPage.preselectArea.visible).notOk('Enablement area is not collapsed'); - // Expand Enablement area - await t.click(workbenchPage.expandPreselectAreaButton); - // Validate that Enablement area is displayed - await t.expect(workbenchPage.preselectArea.visible).ok('Enablement area is not expanded'); }); +test('Verify that user can expand/collapse the enablement area', async t => { + // Hover over Enablement area + await t.hover(workbenchPage.preselectArea); + // Collapse the area with default scripts + await t.click(workbenchPage.collapsePreselectAreaButton); + // Validate that Enablement area is not displayed + await t.expect(workbenchPage.preselectArea.visible).notOk('Enablement area is not collapsed'); + // Expand Enablement area + await t.click(workbenchPage.expandPreselectAreaButton); + // Validate that Enablement area is displayed + await t.expect(workbenchPage.preselectArea.visible).ok('Enablement area is not expanded'); +}); test('Verify that user can see the [Manual] option in the Enablement area', async t => { - const optionsForCheck = [ - 'Manual', - 'List the Indices', - 'Index info', - 'Search', - 'Aggregate' - ]; + const optionsForCheck = [ + 'Manual', + 'List the Indices', + 'Index info', + 'Search', + 'Aggregate' + ]; - // Remember the options displayed in the area - const countOfOptions = await workbenchPage.preselectButtons.count; - const displayedOptions: string[] = []; - for(let i = 0; i < countOfOptions; i++) { - displayedOptions.push(await workbenchPage.preselectButtons.nth(i).textContent); - } - // Verify the options in the area - for(let i = 0; i < countOfOptions; i++) { - await t.expect(displayedOptions[i]).eql(optionsForCheck[i], `Option ${optionsForCheck} is not in the Enablement area`); - } - }); + // Remember the options displayed in the area + const countOfOptions = await workbenchPage.preselectButtons.count; + const displayedOptions: string[] = []; + for(let i = 0; i < countOfOptions; i++) { + displayedOptions.push(await workbenchPage.preselectButtons.nth(i).textContent); + } + // Verify the options in the area + for(let i = 0; i < countOfOptions; i++) { + await t.expect(displayedOptions[i]).eql(optionsForCheck[i], `Option ${optionsForCheck} is not in the Enablement area`); + } +}); test('Verify that user can see saved article in Enablement area when he leaves Workbench page and goes back again', async t => { - await t.click(workbenchPage.documentButtonInQuickGuides); - await t.expect(workbenchPage.internalLinkWorkingWithHashes.visible).ok('The working with hachs link is not visible', { timeout: 5000 }); - // Open Working with Hashes section - await t.click(workbenchPage.internalLinkWorkingWithHashes); - // Check the button from Hash page is visible - await t.expect(workbenchPage.preselectHashCreate.visible).ok('The end of the page is not visible'); - // Go to Browser page - await t.click(myRedisDatabasePage.NavigationPanel.browserButton); - // Go back to Workbench page - await t.click(myRedisDatabasePage.NavigationPanel.workbenchButton); - // Verify that the same article is opened in Enablement area - await t.expect(workbenchPage.preselectHashCreate.visible).ok('The end of the page is not visible'); - // Go to list of DBs page - await t.click(myRedisDatabasePage.NavigationPanel.myRedisDBButton); - // Go back to active DB again - await myRedisDatabasePage.clickOnDBByName(ossStandaloneConfig.databaseName); - // Check that user is on Workbench page and "Working with Hashes" page is displayed - await t.expect(workbenchPage.preselectHashCreate.visible).ok('The end of the page is not visible'); - }); + await t.click(workbenchPage.documentButtonInQuickGuides); + await t.expect(workbenchPage.internalLinkWorkingWithHashes.visible).ok('The working with hachs link is not visible', { timeout: 5000 }); + // Open Working with Hashes section + await t.click(workbenchPage.internalLinkWorkingWithHashes); + // Check the button from Hash page is visible + await t.expect(workbenchPage.preselectHashCreate.visible).ok('The end of the page is not visible'); + // Go to Browser page + await t.click(myRedisDatabasePage.NavigationPanel.browserButton); + // Go back to Workbench page + await t.click(myRedisDatabasePage.NavigationPanel.workbenchButton); + // Verify that the same article is opened in Enablement area + await t.expect(workbenchPage.preselectHashCreate.visible).ok('The end of the page is not visible'); + // Go to list of DBs page + await t.click(myRedisDatabasePage.NavigationPanel.myRedisDBButton); + // Go back to active DB again + await myRedisDatabasePage.clickOnDBByName(ossStandaloneConfig.databaseName); + // Check that user is on Workbench page and "Working with Hashes" page is displayed + await t.expect(workbenchPage.preselectHashCreate.visible).ok('The end of the page is not visible'); +}); //skipped due the issue RI-2384 test.skip('Verify that user can see saved scroll position in Enablement area when he leaves Workbench page and goes back again', async t => { - // Open Working with Hashes section - await t.click(workbenchPage.documentButtonInQuickGuides); - await t.click(workbenchPage.internalLinkWorkingWithHashes); - // Evaluate the last button in Enablement Area - const buttonsQuantity = await workbenchPage.preselectButtons.count; - const lastButton = workbenchPage.preselectButtons.nth(buttonsQuantity - 1); - // Scroll to the very bottom of the page - await t.scrollIntoView(lastButton); - // Check the scroll position - const scrollPosition = await workbenchPage.scrolledEnablementArea.scrollTop; - // Go to Browser page - await t.click(myRedisDatabasePage.NavigationPanel.browserButton); - // Go back to Workbench page - await t.click(myRedisDatabasePage.NavigationPanel.workbenchButton); - // Check that scroll position is saved - await t.expect(await workbenchPage.scrolledEnablementArea.scrollTop).eql(scrollPosition, 'The scroll position status is incorrect'); - // Go to list of DBs page - await t.click(myRedisDatabasePage.NavigationPanel.myRedisDBButton); - // Go back to active DB again - await myRedisDatabasePage.clickOnDBByName(ossStandaloneConfig.databaseName); - // Check that scroll position is saved - await t.expect(await workbenchPage.scrolledEnablementArea.scrollTop).eql(scrollPosition, 'Scroll position is not correct'); - }); + // Open Working with Hashes section + await t.click(workbenchPage.documentButtonInQuickGuides); + await t.click(workbenchPage.internalLinkWorkingWithHashes); + // Evaluate the last button in Enablement Area + const buttonsQuantity = await workbenchPage.preselectButtons.count; + const lastButton = workbenchPage.preselectButtons.nth(buttonsQuantity - 1); + // Scroll to the very bottom of the page + await t.scrollIntoView(lastButton); + // Check the scroll position + const scrollPosition = await workbenchPage.scrolledEnablementArea.scrollTop; + // Go to Browser page + await t.click(myRedisDatabasePage.NavigationPanel.browserButton); + // Go back to Workbench page + await t.click(myRedisDatabasePage.NavigationPanel.workbenchButton); + // Check that scroll position is saved + await t.expect(await workbenchPage.scrolledEnablementArea.scrollTop).eql(scrollPosition, 'The scroll position status is incorrect'); + // Go to list of DBs page + await t.click(myRedisDatabasePage.NavigationPanel.myRedisDBButton); + // Go back to active DB again + await myRedisDatabasePage.clickOnDBByName(ossStandaloneConfig.databaseName); + // Check that scroll position is saved + await t.expect(await workbenchPage.scrolledEnablementArea.scrollTop).eql(scrollPosition, 'Scroll position is not correct'); +}); test('Verify that user can see the siblings menu by clicking on page counter element between Back and Next buttons', async t => { - const popoverButtons = [ - 'Introduction', - 'Working with Hashes', - 'Working with JSON', - 'Learn More' - ] + const popoverButtons = [ + 'Introduction', + 'Working with Hashes', + 'Working with JSON', + 'Learn More' + ]; - // Open Working with Hashes section and click on the on page counter - await t.click(workbenchPage.documentButtonInQuickGuides); - await t.expect(workbenchPage.internalLinkWorkingWithHashes.visible).ok('The working with hachs link is not visible', { timeout: 5000 }); - await t.click(workbenchPage.internalLinkWorkingWithHashes); - // Verify that user can see the quick navigation section to navigate between siblings under the scrolling content - await t.expect(workbenchPage.enablementAreaPagination.visible).ok('The quick navigation section is not displayed'); + // Open Working with Hashes section and click on the on page counter + await t.click(workbenchPage.documentButtonInQuickGuides); + await t.expect(workbenchPage.internalLinkWorkingWithHashes.visible).ok('The working with hachs link is not visible', { timeout: 5000 }); + await t.click(workbenchPage.internalLinkWorkingWithHashes); + // Verify that user can see the quick navigation section to navigate between siblings under the scrolling content + await t.expect(workbenchPage.enablementAreaPagination.visible).ok('The quick navigation section is not displayed'); - await t.click(workbenchPage.enablementAreaPagination); - // Verify the siblings menu - await t.expect(workbenchPage.enablementAreaPaginationPopover.visible).ok('The siblings menu is not displayed'); - const countOfButtons = await workbenchPage.paginationPopoverButtons.count; - for (let i = 0; i < countOfButtons; i++) { - let popoverButton = workbenchPage.paginationPopoverButtons.nth(i); - await t.expect(popoverButton.textContent).eql(popoverButtons[i], `The siblings menu button ${popoverButtons[i]} is not displayed`); - } - }); + await t.click(workbenchPage.enablementAreaPagination); + // Verify the siblings menu + await t.expect(workbenchPage.enablementAreaPaginationPopover.visible).ok('The siblings menu is not displayed'); + const countOfButtons = await workbenchPage.paginationPopoverButtons.count; + for (let i = 0; i < countOfButtons; i++) { + const popoverButton = workbenchPage.paginationPopoverButtons.nth(i); + await t.expect(popoverButton.textContent).eql(popoverButtons[i], `The siblings menu button ${popoverButtons[i]} is not displayed`); + } +}); test('Verify that the same type of content is supported in the “Tutorials” as in the “Quick Guides”', async t => { - const tutorialsContent = [ - 'Working with JSON', - 'Vector Similarity Search', - 'Redis for time series', - 'Probabilistic data structures' - ]; - const command = 'HSET bikes:10000 '; + const tutorialsContent = [ + 'Working with JSON', + 'Vector Similarity Search', + 'Redis for time series', + 'Probabilistic data structures' + ]; + const command = 'HSET bikes:10000 '; - // Verify the redis stack links - await t.click(workbenchPage.redisStackTutorialsButton); - const linksCount = await workbenchPage.redisStackLinks.count; - for(let i = 0; i < linksCount; i++) { - await t.expect(workbenchPage.redisStackLinks.nth(i).textContent).eql(tutorialsContent[i], `The link ${tutorialsContent[i]} is in the Enablement area`); - } - // Verify the load script to Editor - await t.click(workbenchPage.vectorSimilitaritySearchButton); - // Verify that user can see the pagination for redis stack pages in Tutorials - await t.expect(workbenchPage.enablementAreaPagination.visible).ok('The user can not see the pagination for redis stack pages'); - await t.expect(workbenchPage.nextPageButton.visible).ok('The user can not see the next page for redis stack pages'); - await t.expect(workbenchPage.prevPageButton.visible).ok('The user can not see the prev page for redis stack pages'); + // Verify the redis stack links + await t.click(workbenchPage.redisStackTutorialsButton); + const linksCount = await workbenchPage.redisStackLinks.count; + for(let i = 0; i < linksCount; i++) { + await t.expect(workbenchPage.redisStackLinks.nth(i).textContent).eql(tutorialsContent[i], `The link ${tutorialsContent[i]} is in the Enablement area`); + } + // Verify the load script to Editor + await t.click(workbenchPage.vectorSimilitaritySearchButton); + // Verify that user can see the pagination for redis stack pages in Tutorials + await t.expect(workbenchPage.enablementAreaPagination.visible).ok('The user can not see the pagination for redis stack pages'); + await t.expect(workbenchPage.nextPageButton.visible).ok('The user can not see the next page for redis stack pages'); + await t.expect(workbenchPage.prevPageButton.visible).ok('The user can not see the prev page for redis stack pages'); - await t.expect(workbenchPage.queryInputScriptArea.textContent).eql('', 'The editor is not empty'); - await t.click(workbenchPage.hashWithVectorButton); - const editorContent = (await workbenchPage.queryInputScriptArea.textContent).replace(/\s/g, ' ') - await t.expect(editorContent).eql(command, 'The selected command is not in the Editor'); - }); + await t.expect(workbenchPage.queryInputScriptArea.textContent).eql('', 'The editor is not empty'); + await t.click(workbenchPage.hashWithVectorButton); + const editorContent = (await workbenchPage.queryInputScriptArea.textContent).replace(/\s/g, ' '); + await t.expect(editorContent).eql(command, 'The selected command is not in the Editor'); +}); diff --git a/tests/e2e/tests/web/regression/workbench/empty-command-history.e2e.ts b/tests/e2e/tests/web/regression/workbench/empty-command-history.e2e.ts index cecc4d1397..fce78be20c 100644 --- a/tests/e2e/tests/web/regression/workbench/empty-command-history.e2e.ts +++ b/tests/e2e/tests/web/regression/workbench/empty-command-history.e2e.ts @@ -11,7 +11,7 @@ const databaseHelper = new DatabaseHelper(); const databaseAPIRequests = new DatabaseAPIRequests(); fixture `Empty command history in Workbench` - .meta({type: 'regression'}) + .meta({ type: 'regression' }) .page(commonUrl) .beforeEach(async t => { await databaseHelper.acceptLicenseTermsAndAddDatabaseApi(ossStandaloneConfig); diff --git a/tests/e2e/tests/web/regression/workbench/import-tutorials.e2e.ts b/tests/e2e/tests/web/regression/workbench/import-tutorials.e2e.ts index af56e3c824..6f9e1c5593 100644 --- a/tests/e2e/tests/web/regression/workbench/import-tutorials.e2e.ts +++ b/tests/e2e/tests/web/regression/workbench/import-tutorials.e2e.ts @@ -158,7 +158,7 @@ test await t.click(myRedisDatabasePage.NavigationPanel.workbenchButton); await workbenchPage.deleteTutorialByName(tutorialName); await t.expect(workbenchPage.tutorialAccordionButton.withText(tutorialName).exists) - .notOk(`${tutorialName} tutorial is not deleted`); + .notOk(`${tutorialName} tutorial is not deleted`); await databaseAPIRequests.deleteStandaloneDatabaseApi(ossStandaloneRedisearch); })('Verify that user can bulk upload data from custom tutorial', async t => { const allKeysResults = ['9Commands Processed', '9Success', '0Errors']; diff --git a/tests/e2e/tests/web/smoke/cli/cli.e2e.ts b/tests/e2e/tests/web/smoke/cli/cli.e2e.ts index 2ff1380b7a..6edb91366e 100644 --- a/tests/e2e/tests/web/smoke/cli/cli.e2e.ts +++ b/tests/e2e/tests/web/smoke/cli/cli.e2e.ts @@ -5,7 +5,7 @@ import { commonUrl, ossStandaloneConfig } from '../../../../helpers/conf'; import { Common } from '../../../../helpers/common'; import { DatabaseAPIRequests } from '../../../../helpers/api/api-database'; import { APIKeyRequests } from '../../../../helpers/api/api-keys'; -import { goBackHistory, openRedisHomePage } from '../../../../helpers/utils'; +import { goBackHistory } from '../../../../helpers/utils'; const myRedisDatabasePage = new MyRedisDatabasePage(); const browserPage = new BrowserPage(); @@ -75,7 +75,7 @@ test.skip('Verify that user can use unblocking command', async t => { // Verify that user input is blocked await t.expect(browserPage.Cli.cliCommandInput.exists).notOk('Cli input is still shown'); // Create new window to unblock the client - await openRedisHomePage(); + await t.click(myRedisDatabasePage.NavigationPanel.myRedisDBButton); await myRedisDatabasePage.clickOnDBByName(ossStandaloneConfig.databaseName); // Open CLI await t.click(browserPage.Cli.cliExpandButton); diff --git a/tests/e2e/web.runner.ts b/tests/e2e/web.runner.ts index c28353bfad..e77ccc1030 100644 --- a/tests/e2e/web.runner.ts +++ b/tests/e2e/web.runner.ts @@ -6,16 +6,16 @@ import testcafe from 'testcafe'; return t .createRunner() .compilerOptions({ - "typescript": { + 'typescript': { configPath: 'tsconfig.testcafe.json', experimentalDecorators: true - }}) + } }) .src((process.env.TEST_FILES || 'tests/web/**/*.e2e.ts').split('\n')) .browsers(['chromium:headless --cache --allow-insecure-localhost --ignore-certificate-errors']) .screenshots({ path: 'report/screenshots/', takeOnFails: true, - pathPattern: '${OS}_${BROWSER}/${DATE}_${TIME}/${FIXTURE}_${TEST}_${FILE_INDEX}.png', + pathPattern: '${OS}_${BROWSER}/${DATE}_${TIME}/${FIXTURE}_${TEST}_${FILE_INDEX}.png' }) .reporter([ 'spec', @@ -47,7 +47,7 @@ import testcafe from 'testcafe'; process.exit(failedCount); }) .catch((e) => { - console.error(e) + console.error(e); process.exit(1); }); })();