Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
bfd0864
RI-7744: fix key tests + change e2e trigger temporary
ArtemHoruzhenko Nov 20, 2025
a15609f
RI-7744: fix keys list tests
ArtemHoruzhenko Nov 20, 2025
b2d4563
RI-7744: fix pub-sub tests
ArtemHoruzhenko Nov 20, 2025
fad464a
RI-7744: fix add key tests
ArtemHoruzhenko Nov 20, 2025
9cd0fe4
RI-7744: fix keys list/tree tests
ArtemHoruzhenko Nov 20, 2025
789c1d1
RI-7744: fix keys list full screen tests
ArtemHoruzhenko Nov 20, 2025
ce78c9f
RI-7744: fix keys list scroll + streams tests
ArtemHoruzhenko Nov 20, 2025
0fca8c9
RI-7744: fix keys list scroll + streams tests
ArtemHoruzhenko Nov 20, 2025
5b72998
RI-7744: fix dbsize test fix
ArtemHoruzhenko Nov 20, 2025
a641404
RI-7744: fix db sorting test
ArtemHoruzhenko Nov 20, 2025
1b630a4
RI-7744: fix navigation tests
ArtemHoruzhenko Nov 20, 2025
5d5f5b1
RI-7744: fix shortcuts tests
ArtemHoruzhenko Nov 20, 2025
ffbb24f
RI-7744: fix confirm popover test
ArtemHoruzhenko Nov 20, 2025
c7cfaa1
RI-7744: fix db info tooltip
ArtemHoruzhenko Nov 20, 2025
6731b70
RI-7744: skip pubsub tests
ArtemHoruzhenko Nov 20, 2025
236bbde
RI-7744: fix search capabilities
ArtemHoruzhenko Nov 21, 2025
2f259bc
RI-7744: fix pub sub tests
ArtemHoruzhenko Nov 21, 2025
bccb37a
RI-7744: fix browser context tests
ArtemHoruzhenko Nov 21, 2025
5e40bd4
RI-7744: fix cli helper tests
ArtemHoruzhenko Nov 21, 2025
137a694
RI-7744: fix key filter tests
ArtemHoruzhenko Nov 21, 2025
78cbd2d
RI-7744: fix key filter 2 tests
ArtemHoruzhenko Nov 21, 2025
ea59cc1
RI-7744: fix typo
ArtemHoruzhenko Dec 1, 2025
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
3 changes: 3 additions & 0 deletions .github/workflows/tests-e2e.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
name: ✅ E2E Tests
Copy link
Member

Choose a reason for hiding this comment

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

Note: Since we already have variations of labels that trigger the different types of tests, you can also extend them with one more, targeting the e2e tests 🙂

Image

Copy link
Contributor Author

Choose a reason for hiding this comment

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

sure. we will do it eventually


on:
push:
branches:
- 'e2e/**'
workflow_dispatch:
inputs:
debug:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,18 @@ const MessagesListTable = () => {

<Row align="center" gap="s">
<Text>Messages:</Text>
<Text>{messages.length}</Text>
<Text data-testid="pub-sub-messages-count">
{messages.length}
</Text>
</Row>
</Row>

<Row align="center" justify="end" gap="s">
<Row
align="center"
justify="end"
gap="s"
data-testid="pub-sub-status"
>
<Text>Status:</Text>
{isSubscribed ? (
<RiBadge label="Subscribed" variant="success" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,11 @@ const PublishMessage = () => {
</Row>

{isShowBadge && (
<ResultWrapper grow={false} align="center">
<ResultWrapper
grow={false}
align="center"
data-testid="publish-result"
>
<Icon icon={ToastCheckIcon} color="success500" />
<Text color="success">
{getClientsText(
Expand Down
5 changes: 3 additions & 2 deletions tests/e2e/pageObjects/browser-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,10 +215,11 @@ export class BrowserPage extends InstancePage {
keysSummary = Selector('[data-testid=keys-summary]');
multiSearchArea = Selector(this.cssFilteringLabel);
keyDetailsHeader = Selector('[data-testid=key-details-header]');
keysContainer = Selector('[id=keys]');
keyListTable = Selector('[data-testid=keyList-table]');
keyListMessage = Selector('[data-testid=no-result-found-msg]');
keyDetailsTable = Selector('[data-testid=key-details]');
keyNameFormDetails = Selector('[data-testid=key-name-text]');
keyNameFormDetails = Selector('p[data-testid=edit-key-input]');
keyDetailsTTL = Selector('[data-testid=key-ttl-text]');
progressLine = Selector('div.euiProgress');
progressKeyList = Selector('[data-testid=progress-key-list]');
Expand All @@ -244,7 +245,7 @@ export class BrowserPage extends InstancePage {
jsonValue = Selector('[data-testid=value-as-json]');
stringValueAsJson = Selector(this.cssJsonValue);
// POPUPS
changeValueWarning = Selector('[data-testid=approve-popover]');
changeValueWarning = Selector('[data-testid=confirm-popover]');
// TABLE
keyListItem = Selector('[role=rowgroup] [role=row]');
// Dialog
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export class CommandHelper {
returnToList = Selector('[data-testid=cli-helper-back-to-list-btn]');
filterGroupTypeButton = Selector('[data-testid=select-filter-group-type]');
filterOptionGroupType = Selector('[data-test-subj^=filter-option-group-type-]');
clearAllGroupFilters = Selector('[data-testid=select-filter-group-type] button title').withExactText('Clear All').parent('button');
clearAllGroupFilters = Selector('[data-testid=cli-helper] button[title="Clear All"]');

//TEXT ELEMENTS
cliHelper = Selector('[data-testid=cli-helper]');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export class NavigationHeader {
cloudSignInButton = Selector('[data-testid=cloud-sign-in-btn]');
copilotButton = Selector('[data-testid=copilot-trigger]');
dbName = Selector('[data-testid=nav-instance-popover-btn]');
dbNameExactText = Selector('[data-testid=nav-instance-popover-btn] b');
dbNameExactText = Selector('[data-testid=nav-instance-popover-btn] p');
homeLinkNavigation = Selector('[class*=homePageLink]');
dbListInstance = Selector('[data-testid^=instance-item-]');
rdiNavigationTab = Selector('[role=tab][id*="Redis Data Integration"]');
Expand Down
4 changes: 2 additions & 2 deletions tests/e2e/pageObjects/components/shortcuts-panel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ export class ShortcutsPanel {
//*The following categories are ordered alphabetically (Alerts, Buttons, Checkboxes, etc.).
//-------------------------------------------------------------------------------------------
//BUTTONS
shortcutsCloseButton = Selector('[role=dialog][title=Shortcuts] button title').withText('Cancel');
shortcutsCloseButton = Selector('[role=dialog][title=Shortcuts] button[title=Close]');
//TEXT ELEMENTS
shortcutsTitle = Selector('[role=dialog][title=Shortcuts] h3');
shortcutsTitle = Selector('[role=dialog][title=Shortcuts] [data-role="drawer-heading"]');
shortcutsDesktopApplicationSection = Selector('[data-test-subj="shortcuts-section-Desktop application"]');
shortcutsCLISection = Selector('[data-test-subj=shortcuts-section-CLI]');
shortcutsWorkbenchSection = Selector('[data-test-subj=shortcuts-section-Workbench]');
Expand Down
6 changes: 3 additions & 3 deletions tests/e2e/pageObjects/my-redis-databases-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ export class MyRedisDatabasePage extends BaseOverviewPage {
popoverHeader = Selector('#formModalHeader');
submitChangesButton = Selector('[data-testid=btn-submit]');
promoButton = Selector('[data-testid=promo-btn]');
sortByDatabaseAlias = Selector('span').withAttribute('title', 'Database Alias');
sortByHostAndPort = Selector('span').withAttribute('title', 'Host:Port');
sortByConnectionType = Selector('span').withAttribute('title', 'Connection Type');
sortByDatabaseAlias = Selector('table th').withText('Database Alias');
sortByHostAndPort = Selector('table th').withText('Host:Port');
sortByConnectionType = Selector('table th').withText('Connection Type');
importDatabasesBtn = Selector('[data-testid=option-btn-import]');
retryImportBtn = Selector('[data-testid=btn-retry]');
removeImportedFileBtn = Selector('[aria-label="Clear selected files"]');
Expand Down
19 changes: 12 additions & 7 deletions tests/e2e/pageObjects/pub-sub-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,24 @@ import { InstancePage } from './instance-page';

export class PubSubPage extends InstancePage {
//CSS Selectors
cssSelectorMessage = '[data-testid^=row]';
cssSelectorMessage = '[data-testid="messages-list"] tr';
//-------------------------------------------------------------------------------------------
//DECLARATION OF SELECTORS
//*Declare all elements/components of the relevant page.
//*Target any element/component via data-id, if possible!
//*The following categories are ordered alphabetically (Alerts, Buttons, Checkboxes, etc.).
//-------------------------------------------------------------------------------------------
//COMPONENTS
subscribeStatus = Selector('[data-testid=subscribe-status-text]');
messages = Selector('[data-testid^=row]');
totalMessagesCount = Selector('[data-testid=messages-count]');
initialPage = Selector('[data-testid=pub-sub-page] [data-testid="empty-messages-list"]')
subscribeStatus = Selector('[data-testid=pub-sub-status]');
messages = Selector('[data-testid="messages-list"] tr');
messagesTable = Selector('[data-testid="messages-list"] table')
messagesTableBottomNav = Selector('[data-testid="messages-list"] nav[data-role=pagination]')
messagesTableFirstPageBtn = Selector('[data-testid="messages-list"] nav[data-role=pagination] button[title="First page"]')
messagesTableLastPageBtn = Selector('[data-testid="messages-list"] nav[data-role=pagination] button[title="Last page"]')
totalMessagesCount = Selector('[data-testid=pub-sub-messages-count]');
pubSubPageContainer = Selector('[data-testid=pub-sub-page]');
clientBadge = Selector('[data-testid=affected-clients-badge]');
publishResult = Selector('[data-testid=publish-result]');
clearButtonTooltip = Selector('[data-radix-popper-content-wrapper]');
ossClusterEmptyMessage = Selector('[data-testid=empty-messages-list-cluster]');
//BUTTONS
Expand All @@ -30,7 +35,7 @@ export class PubSubPage extends InstancePage {
channelsSubscribeInput = Selector('[data-testid=channels-input]');

patternsCount = Selector('[data-testid=patterns-count]');
messageCount = Selector('[data-testid=messages-count]');
messageCount = Selector('[data-testid=pub-sub-messages-count]');

/**
* Publish message in pubsub
Expand All @@ -55,6 +60,6 @@ export class PubSubPage extends InstancePage {
// Wait for pubsub loading
await t.wait(1000);
await this.publishMessage(channel, message);
await t.expect((this.pubSubPageContainer.find('[data-testid^=row]').withText('message')).exists).ok('Message is not displayed');
await t.expect((this.messages.withText('message')).exists).ok('Message is not displayed');
}
}
5 changes: 5 additions & 0 deletions tests/e2e/tests/web/critical-path/browser/context.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Common } from '../../../../helpers/common';
import { KeyTypesTexts, rte } from '../../../../helpers/constants';
import { DatabaseAPIRequests } from '../../../../helpers/api/api-database';
import { verifySearchFilterValue } from '../../../../helpers/keys';
import { t } from 'testcafe'

const myRedisDatabasePage = new MyRedisDatabasePage();
const browserPage = new BrowserPage();
Expand All @@ -20,6 +21,8 @@ fixture `Browser Context`
.page(commonUrl)
.beforeEach(async() => {
await databaseHelper.acceptLicenseTermsAndAddDatabaseApi(ossStandaloneConfig);
// Force switch to list view
await t.click(browserPage.browserViewButton);
})
// Update after resolving https://redislabs.atlassian.net/browse/RI-3299
test.skip('Verify that user can see saved CLI size on Browser page when he returns back to Browser page', async t => {
Expand Down Expand Up @@ -87,6 +90,8 @@ test('Verify that user can see saved executed commands in CLI on Browser page wh
test
.before(async() => {
await databaseHelper.acceptLicenseTermsAndAddDatabaseApi(ossStandaloneBigConfig);
// Force switch to list view
await t.click(browserPage.browserViewButton);
})('Verify that user can see key details selected when he returns back to Browser page', async t => {
// Scroll keys elements
const scrollY = 1000;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,10 @@ test
}
});
test
.before(async() => {
.before(async(t) => {
await databaseHelper.acceptLicenseTermsAndAddDatabaseApi(ossStandaloneBigConfig);
// Force switch to list view
await t.click(browserPage.browserViewButton);
})('Verify that user see the key type label when filtering per key types and when removes label the filter is removed on Browser page', async t => { //Check filtering labels
for (const { textType } of keyTypes) {
await browserPage.selectFilterGroupType(textType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ fixture `Browser - Specify Keys to Scan`
.meta({ type: 'critical_path', rte: rte.standalone })
.page(commonUrl)
.clientScripts({ content: `(${explicitErrorHandler.toString()})()` })
.beforeEach(async() => {
.beforeEach(async(t) => {
await databaseHelper.acceptLicenseTermsAndAddDatabaseApi(ossStandaloneConfig);
// Force switch to list view
await t.click(browserPage.browserViewButton);
})
.afterEach(async t => {
//Clear and delete database
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ test
.before(async() => {
await databaseHelper.acceptLicenseTermsAndAddDatabaseApi(ossStandaloneConfig);
keyName = Common.generateWord(10);
// Force switch to list view
await t.click(browserPage.browserViewButton);
})
.after(async() => {
// Clear and delete database
Expand Down Expand Up @@ -148,6 +150,8 @@ test
test
.before(async() => {
await databaseHelper.acceptLicenseTermsAndAddDatabaseApi(ossStandaloneBigConfig);
// Force switch to list view
await t.click(browserPage.browserViewButton);
})
.after(async() => {
// Clear and delete database
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ test('Verify Command Helper search and filter', async t => {
await t.expect(browserPage.CommandHelper.cliHelperOutputTitles.count).gt(0, 'List of commands were not found');
// Clear search input
// todo: add proper attr to html
const clearButton = browserPage.CommandHelper.cliHelper.find('button title').withExactText('Cancel').parent('button');
const clearButton = browserPage.CommandHelper.cliHelper.find('button[title=Reset]');
await t.click(clearButton);
// Verify that when user clears the input in the Search of CLI Helper (via x icon), he can see the default screen with proper the text
await t.expect(browserPage.CommandHelper.cliHelperText.textContent).eql(defaultHelperText, 'Default text for CLI Helper is not shown');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,18 @@ test('Verify that when user subscribe to the pubsub channel he can see all the m
// Verify that the Message field placeholder is 'Enter Message'
await t.expect(pubSubPage.messageInput.getAttribute('placeholder')).eql('Enter Message', 'No placeholder in Message field');
// Verify that user is unsubscribed from the pubsub channel when he go to the pubsub window after launching application for the first time
await t.expect(pubSubPage.subscribeStatus.textContent).eql('You are not subscribed', 'User is not unsubscribed');
await t.expect(pubSubPage.initialPage.textContent).contains('You are not subscribed', 'User is not unsubscribed');
await t.expect(pubSubPage.subscribeButton.exists).eql(true, 'Subscribe button is not displayed');

// Subscribe to channel
await t.click(pubSubPage.subscribeButton);
await t.expect(pubSubPage.subscribeStatus.textContent).eql('You are subscribed', 'User is not subscribed', { timeout: 10000 });
await t.expect(pubSubPage.subscribeStatus.textContent).contains('Subscribed', 'User is not subscribed', { timeout: 10000 });
// Verify that user can publish a message to a channel
await pubSubPage.publishMessage('test', 'published message');
await verifyMessageDisplayingInPubSub('published message', true);
await t.click(pubSubPage.unsubscribeButton);
//Verify that when user unsubscribe from a pubsub channel he can see no new data being published to the channel from the moment he unsubscribe
await t.expect(pubSubPage.subscribeStatus.textContent).eql('You are not subscribed', 'User is not unsubscribed', { timeout: 10000 });
await t.expect(pubSubPage.subscribeStatus.textContent).contains('Unsubscribed', 'User is not unsubscribed', { timeout: 10000 });
//Verify that user can publish a message regardless of my subscription state.
await pubSubPage.publishMessage('test', 'message in unsubscribed status');
//Verify that message is not displayed
Expand All @@ -57,15 +57,15 @@ test('Verify that when user subscribe to the pubsub channel he can see all the m
test('Verify that the focus gets always shifted to a newest message (auto-scroll)', async t => {
await pubSubPage.subsribeToChannelAndPublishMessage('test', 'first message');
// Verify that when user click Publish and the publication is successful, he can see a response: badge with the number <# of clients received>
await t.expect(pubSubPage.clientBadge.exists).ok('Client badge is not displayed');
await t.expect(pubSubPage.clientBadge.textContent).contains('1', 'Client badge is not displayed', { timeout: 10000 });
await t.expect(pubSubPage.publishResult.exists).ok('Publish results is not displayed');
await t.expect(pubSubPage.publishResult.textContent).contains('Published (1)', 'Publish result is not displayed', { timeout: 10000 });

// Go to Redis Databases Page
await myRedisDatabasePage.navigateToDatabase(ossStandaloneConfig.databaseName);
// Go back to PubSub page
await t.click(browserPage.NavigationTabs.pubSubButton);
// Verify that my subscription state is preserved when user navigate through the app while connected to current database and in current app session
await t.expect(pubSubPage.subscribeStatus.textContent).eql('You are subscribed', 'User is not subscribed', { timeout: 10000 });
await t.expect(pubSubPage.subscribeStatus.textContent).contains('Subscribed', 'User is not subscribed', { timeout: 10000 });

// Publish 100 messages
await pubSubPage.Cli.sendCommandInCli('100 publish channel test100Message');
Expand All @@ -92,7 +92,7 @@ test
await myRedisDatabasePage.clickOnDBByName(ossStandaloneV5Config.databaseName);
// Verify no subscription, messages and total messages
await t.click(browserPage.NavigationTabs.pubSubButton);
await t.expect(pubSubPage.subscribeStatus.textContent).eql('You are not subscribed', 'User is not unsubscribed', { timeout: 10000 });
await t.expect(pubSubPage.initialPage.textContent).contains('You are not subscribed', 'User is not unsubscribed');
await verifyMessageDisplayingInPubSub('message', false);
await t.expect(pubSubPage.totalMessagesCount.exists).notOk('Total counter is still displayed');
});
Expand Down Expand Up @@ -148,7 +148,8 @@ test('Verify that the Message field input is preserved until user Publish a mess
// Verify that the Channel field input is preserved until user modify it (publishing a message does not clear the field)
await t.expect(pubSubPage.channelNameInput.value).eql('testChannel', 'Channel input is empty', { timeout: 10000 });
});
test.requestHooks(logger)('Verify that user can clear all the messages from the pubsub window', async t => {
// todo: fix after "clear" button will be added
test.skip.requestHooks(logger)('Verify that user can clear all the messages from the pubsub window', async t => {
await pubSubPage.subsribeToChannelAndPublishMessage('testChannel', 'message');
await pubSubPage.publishMessage('testChannel2', 'second m');
// Verify the tooltip text 'Clear Messages' appears on hover the clear button
Expand Down
4 changes: 3 additions & 1 deletion tests/e2e/tests/web/regression/browser/add-keys.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,10 @@ test('Verify that user can create different types(string, number, null, array, b
});
// https://redislabs.atlassian.net/browse/RI-3995
test
.before(async() => {
.before(async(t) => {
await databaseHelper.acceptLicenseTermsAndAddDatabaseApi(ossStandaloneBigConfig);
// Force switch to list view
await t.click(browserPage.browserViewButton);
})
.after(async() => {
let commandString = 'DEL';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ let keys: string[];
fixture `Filtering iteratively in Browser page`
.meta({ type: 'regression' })
.page(commonUrl)
.beforeEach(async() => {
.beforeEach(async(t) => {
await databaseHelper.acceptLicenseTermsAndAddDatabaseApi(ossStandaloneConfig);
await browserPage.Cli.sendCommandInCli('flushdb');
// Force switch to list view
await t.click(browserPage.browserViewButton);
})
.afterEach(async() => {
// Clear and delete database
Expand Down Expand Up @@ -50,8 +52,10 @@ test
});
test
.meta({ rte: rte.ossCluster })
.before(async() => {
.before(async(t) => {
await databaseHelper.acceptLicenseTermsAndAddOSSClusterDatabase(ossClusterConfig);
// Force switch to list view
await t.click(browserPage.browserViewButton);
})
.after(async() => {
// Clear and delete database
Expand All @@ -73,9 +77,11 @@ test
});
test
.meta({ rte: rte.standalone })
.before(async() => {
.before(async(t) => {
// Add Big standalone DB
await databaseHelper.acceptLicenseTermsAndAddDatabaseApi(ossStandaloneBigConfig);
// Force switch to list view
await t.click(browserPage.browserViewButton);
})('Verify that user use Scan More in DB with 10-50 millions of keys (when search by pattern/)', async t => {
// Search all string keys
await browserPage.searchByKeyName('*');
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/tests/web/regression/browser/filtering.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ test('Verify that when user clicks on “clear” control with no filter per key
}, ossStandaloneConfig);
// Search for not existed key name
await browserPage.searchByKeyName(keyName2);
await t.expect(browserPage.keyListTable.textContent).contains('No results found.', 'Key is not found message not displayed');
await t.expect(browserPage.keysContainer.textContent).contains('No results found.', 'Key is not found message not displayed');
// Verify that when user clicks on “clear” control and filter per key name is applied filter is reset and rescan initiated
await t.click(browserPage.clearFilterButton);
await t.expect(browserPage.filterByPatterSearchInput.getAttribute('value')).eql('', 'The filtering is not reset');
Expand Down
Loading
Loading