Skip to content

Commit 86546a3

Browse files
Merge pull request #809 from RedisInsight/feature/e2e-ack-claim-tests
e2e - ack and claim tests
2 parents 1397e4b + fdac62d commit 86546a3

File tree

4 files changed

+181
-3
lines changed

4 files changed

+181
-3
lines changed

redisinsight/ui/src/pages/browser/components/stream-details/messages-view/MessageClaimPopover/MessageClaimPopover.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ const getConsumersOptions = (consumers: ConsumerDto[]) => (
3232
consumers.map((consumer) => ({
3333
value: consumer.name,
3434
inputDisplay: (
35-
<EuiText size="m" className={styles.option}>
35+
<EuiText size="m" className={styles.option} data-testid="consumer-option">
3636
<EuiText className={styles.consumerName}>{consumer.name}</EuiText>
3737
<EuiText size="s" className={styles.pendingCount} data-testid="pending-count">
3838
{`pending: ${consumer.pending}`}

tests/e2e/pageObjects/browser-page.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,11 @@ export class BrowserPage {
7272
confirmRemoveEntryButton = Selector('[data-testid^=remove-entry-button-]').withExactText('Remove');
7373
clearStreamEntryInputs = Selector('[data-testid=remove-item]');
7474
saveGroupsButton = Selector('[data-testid=save-groups-btn]');
75+
acknowledgeButton = Selector('[data-testid=acknowledge-btn]');
76+
confirmAcknowledgeButton = Selector('[data-testid=acknowledge-submit]');
77+
claimPendingMessageButton = Selector('[data-testid=claim-pending-message]');
78+
submitButton = Selector('[data-testid=btn-submit]');
79+
consumerDestinationSelect = Selector('[data-testid=destination-select]');
7580
removeConsumerButton = Selector('[data-testid^=remove-consumer-button]');
7681
removeConsumerGroupButton = Selector('[data-testid^=remove-groups-button]');
7782
//CONTAINERS
@@ -80,6 +85,7 @@ export class BrowserPage {
8085
breadcrumbsContainer = Selector('[data-testid=breadcrumbs-container]');
8186
virtualTableContainer = Selector('[data-testid=virtual-table-container]');
8287
streamEntriesContainer = Selector('[data-testid=stream-entries-container]');
88+
streamMessagesContainer = Selector('[data-testid=stream-messages-container]');
8389
//LINKS
8490
internalLinkToWorkbench = Selector('[data-testid=internal-workbench-link]');
8591
//OPTION ELEMENTS
@@ -95,8 +101,10 @@ export class BrowserPage {
95101
filterOptionType = Selector('[data-test-subj^=filter-option-type-]');
96102
filterByKeyTypeDropDown = Selector('[data-testid=filter-option-type-default]');
97103
filterOptionTypeSelected = Selector('[data-testid^=filter-option-type-selected]');
104+
consumerOption = Selector('[data-testid=consumer-option]');
98105
//TABS
99106
streamTabGroups = Selector('[data-testid=stream-tab-Groups]');
107+
streamTabConsumers = Selector('[data-testid=stream-tab-Consumers]');
100108
streamTabs = Selector('[data-test-subj=stream-tabs]');
101109
//TEXT INPUTS (also referred to as 'Text fields')
102110
addKeyNameInput = Selector('[data-testid=key]');
@@ -125,10 +133,10 @@ export class BrowserPage {
125133
streamValue = Selector('[data-testid=field-value]');
126134
addStreamRow = Selector('[data-testid=add-new-item]');
127135
streamFieldsValues = Selector('[data-testid^=stream-entry-field-]');
128-
streamRangeStartInput = Selector('._3MW0_WsJsq1s4bsuMNXOaV');
129136
streamRangeEndInput = Selector('[data-testid=range-end-input]');
130137
groupNameInput = Selector('[data-testid=group-name-field]');
131138
consumerIdInput = Selector('[data-testid=id-field]');
139+
streamMinIdleTimeInput = Selector('[data-testid=min-idle-time]');
132140
//TEXT ELEMENTS
133141
keySizeDetails = Selector('[data-testid=key-size-text]');
134142
keyLengthDetails = Selector('[data-testid=key-length-text]');
@@ -193,12 +201,13 @@ export class BrowserPage {
193201
streamRangeRightTimestamp = Selector('[data-testid=range-right-timestamp]');
194202
streamGroupId = Selector('.streamItemId[data-testid^=stream-group-id]');
195203
streamGroupName = Selector('[data-testid^=stream-group-name]');
196-
streamMessage = Selector('[data-testid^=stream-message]');
204+
streamMessage = Selector('[data-testid*=-date][data-testid^=stream-message]');
197205
streamConsumerName = Selector('[data-testid^=stream-consumer-]');
198206
consumerGroup = Selector('[data-testid^=stream-group-]');
199207
entryIdInfoIcon = Selector('[data-testid=entry-id-info-icon]');
200208
errorMessage = Selector('[data-test-subj=toast-error]');
201209
entryIdError = Selector('[data-testid=id-error]');
210+
pendingCount = Selector('[data-testid=pending-count]');
202211
lastRefreshMessage = Selector('[data-testid=refresh-message]');
203212

204213
/**
@@ -772,6 +781,17 @@ export class BrowserPage {
772781
}
773782
await t.click(this.saveGroupsButton);
774783
}
784+
785+
/**
786+
* Open pendings view in Stream key
787+
* @keyName The name of the Stream Key
788+
*/
789+
async openStreamPendingsView(keyName: string): Promise<void> {
790+
await this.openKeyDetails(keyName);
791+
await t.click(this.streamTabGroups);
792+
await t.click(this.consumerGroup);
793+
await t.click(this.streamConsumerName);
794+
}
775795
}
776796

777797
/**
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import { Chance } from 'chance';
2+
import { rte } from '../../../helpers/constants';
3+
import { acceptLicenseTermsAndAddDatabase, deleteDatabase } from '../../../helpers/database';
4+
import { BrowserPage, CliPage } from '../../../pageObjects';
5+
import {
6+
commonUrl,
7+
ossStandaloneConfig
8+
} from '../../../helpers/conf';
9+
10+
const browserPage = new BrowserPage();
11+
const cliPage = new CliPage();
12+
const chance = new Chance();
13+
14+
let keyName = chance.word({ length: 20 });
15+
let consumerGroupName = chance.word({ length: 20 });
16+
17+
fixture `Acknowledge and Claim of Pending messages`
18+
.meta({ type: 'critical_path', rte: rte.standalone })
19+
.page(commonUrl)
20+
.beforeEach(async() => {
21+
await acceptLicenseTermsAndAddDatabase(ossStandaloneConfig, ossStandaloneConfig.databaseName);
22+
})
23+
.afterEach(async t => {
24+
//Clear and delete database
25+
if (await t.expect(browserPage.closeKeyButton.visible).ok()){
26+
await t.click(browserPage.closeKeyButton);
27+
}
28+
await browserPage.deleteKeyByName(keyName);
29+
await deleteDatabase(ossStandaloneConfig.databaseName);
30+
});
31+
test('Verify that user can acknowledge any message in the list of pending messages', async t => {
32+
keyName = chance.word({ length: 20 });
33+
consumerGroupName = chance.word({ length: 20 });
34+
const cliCommands = [
35+
`XGROUP CREATE ${keyName} ${consumerGroupName} $ MKSTREAM`,
36+
`XADD ${keyName} * message apple`,
37+
`XREADGROUP GROUP ${consumerGroupName} Alice COUNT 1 STREAMS ${keyName} >`
38+
];
39+
// Add New Stream Key with pending message
40+
for(const command of cliCommands){
41+
await cliPage.sendCommandInCli(command);
42+
}
43+
// Open Stream pendings view
44+
await browserPage.openStreamPendingsView(keyName);
45+
await t.click(browserPage.fullScreenModeButton);
46+
// Acknowledge message and check result
47+
await t.click(browserPage.acknowledgeButton);
48+
await t.expect(browserPage.confirmationMessagePopover.textContent).contains('will be acknowledged and removed from the pending messages list', 'The confirmation message');
49+
await t.click(browserPage.confirmAcknowledgeButton);
50+
await t.expect(browserPage.streamMessagesContainer.textContent).contains('Your Consumer has no pending messages.', 'The messages is acknowledged from the table');
51+
});
52+
test('Verify that user can claim any message in the list of pending messages', async t => {
53+
keyName = chance.word({ length: 20 });
54+
consumerGroupName = chance.word({ length: 20 });
55+
const cliCommands = [
56+
`XGROUP CREATE ${keyName} ${consumerGroupName} $ MKSTREAM`,
57+
`XADD ${keyName} * message apple`,
58+
`XADD ${keyName} * message orange`,
59+
`XREADGROUP GROUP ${consumerGroupName} Alice COUNT 1 STREAMS ${keyName} >`,
60+
`XREADGROUP GROUP ${consumerGroupName} Bob COUNT 1 STREAMS ${keyName} >`
61+
];
62+
// Add New Stream Key with pending message
63+
for(const command of cliCommands){
64+
await cliPage.sendCommandInCli(command);
65+
}
66+
// Open Stream pendings view
67+
await browserPage.openStreamPendingsView(keyName);
68+
await t.click(browserPage.fullScreenModeButton);
69+
// Claim message and check result
70+
await t.click(browserPage.claimPendingMessageButton);
71+
await t.expect(browserPage.pendingCount.textContent).eql('pending: 1', 'The number of pending messages for selected consumer');
72+
await t.click(browserPage.submitButton);
73+
await t.expect(browserPage.streamMessagesContainer.textContent).contains('Your Consumer has no pending messages.', 'The messages is claimed and removed from the table');
74+
await t.click(browserPage.streamTabConsumers);
75+
await t.click(browserPage.streamConsumerName.nth(1));
76+
await t.expect(browserPage.streamMessage.count).eql(2, 'The claimed messages is in the selected Consumer');
77+
});
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { Chance } from 'chance';
2+
import { rte } from '../../../helpers/constants';
3+
import { acceptLicenseTermsAndAddDatabase, deleteDatabase } from '../../../helpers/database';
4+
import { BrowserPage, CliPage } from '../../../pageObjects';
5+
import {
6+
commonUrl,
7+
ossStandaloneConfig
8+
} from '../../../helpers/conf';
9+
10+
const browserPage = new BrowserPage();
11+
const cliPage = new CliPage();
12+
const chance = new Chance();
13+
14+
let keyName = chance.word({ length: 20 });
15+
let consumerGroupName = chance.word({ length: 20 });
16+
17+
fixture `Pending messages`
18+
.meta({ type: 'regression', rte: rte.standalone })
19+
.page(commonUrl)
20+
.beforeEach(async() => {
21+
await acceptLicenseTermsAndAddDatabase(ossStandaloneConfig, ossStandaloneConfig.databaseName);
22+
})
23+
.afterEach(async t => {
24+
//Clear and delete database
25+
if (await t.expect(browserPage.closeKeyButton.visible).ok()){
26+
await t.click(browserPage.closeKeyButton);
27+
}
28+
await browserPage.deleteKeyByName(keyName);
29+
await deleteDatabase(ossStandaloneConfig.databaseName);
30+
});
31+
test('Verify that user can\'t select currently selected Consumer to Claim message in the drop-down', async t => {
32+
keyName = chance.word({ length: 20 });
33+
consumerGroupName = chance.word({ length: 20 });
34+
const consumerNames = [
35+
'Alice',
36+
'Bob'
37+
];
38+
const cliCommands = [
39+
`XGROUP CREATE ${keyName} ${consumerGroupName} $ MKSTREAM`,
40+
`XADD ${keyName} * message apple`,
41+
`XADD ${keyName} * message orange`,
42+
`XREADGROUP GROUP ${consumerGroupName} ${consumerNames[0]} COUNT 1 STREAMS ${keyName} >`,
43+
`XREADGROUP GROUP ${consumerGroupName} ${consumerNames[1]} COUNT 1 STREAMS ${keyName} >`
44+
];
45+
// Add New Stream Key with pending message
46+
for(const command of cliCommands){
47+
await cliPage.sendCommandInCli(command);
48+
}
49+
// Open Stream pendings view
50+
await browserPage.openStreamPendingsView(keyName);
51+
await t.click(browserPage.fullScreenModeButton);
52+
// Click on Claim message and check result
53+
await t.click(browserPage.claimPendingMessageButton);
54+
await t.click(browserPage.consumerDestinationSelect);
55+
await t.expect(browserPage.consumerOption.textContent).notContains(consumerNames[0], 'The currently selected Consumer is not in the drop-down');
56+
});
57+
test('Verify that the message is claimed only if its idle time is greater than the Min Idle Time', async t => {
58+
keyName = chance.word({ length: 20 });
59+
consumerGroupName = chance.word({ length: 20 });
60+
const cliCommands = [
61+
`XGROUP CREATE ${keyName} ${consumerGroupName} $ MKSTREAM`,
62+
`XADD ${keyName} * message apple`,
63+
`XADD ${keyName} * message orange`,
64+
`XREADGROUP GROUP ${consumerGroupName} Alice COUNT 1 STREAMS ${keyName} >`,
65+
`XREADGROUP GROUP ${consumerGroupName} Bob COUNT 1 STREAMS ${keyName} >`
66+
];
67+
// Add New Stream Key with pending message
68+
for(const command of cliCommands){
69+
await cliPage.sendCommandInCli(command);
70+
}
71+
// Open Stream pendings view
72+
await browserPage.openStreamPendingsView(keyName);
73+
await t.click(browserPage.fullScreenModeButton);
74+
const streamMessageBefore = await browserPage.streamMessage.count;
75+
// Claim message and check result when Min Idle Time is greater than the idle time
76+
await t.click(browserPage.claimPendingMessageButton);
77+
await t.typeText(browserPage.streamMinIdleTimeInput, '100000000');
78+
await t.click(browserPage.submitButton);
79+
await t.expect(browserPage.notificationMessage.textContent).contains('No messages claimed', 'The message is not claimed notification');
80+
await t.expect(browserPage.streamMessage.count).eql(streamMessageBefore, 'The number of pendings in the table');
81+
});

0 commit comments

Comments
 (0)