Skip to content

Commit 39b9a25

Browse files
authored
RI-6570 Verify edit list key operations for in the browsers module (#4732)
* added e2e test to verify whether the edit key value functionality is working fine for the list type in the browser module re #RI-6570
1 parent 529bcc1 commit 39b9a25

File tree

2 files changed

+362
-2
lines changed

2 files changed

+362
-2
lines changed

tests/playwright/pageObjects/browser-page.ts

Lines changed: 114 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,9 @@ export class BrowserPage extends BasePage {
484484
this.hashFieldNameInput = page.getByTestId('field-name')
485485
this.hashFieldValueEditor = page.getByTestId('hash_value-editor')
486486
this.hashTtlFieldInput = page.getByTestId('hash-ttl')
487-
this.listKeyElementEditorInput = page.getByTestId('list_value-editor-')
487+
this.listKeyElementEditorInput = page.locator(
488+
'[data-testid^="list_value-editor-"]',
489+
)
488490
this.stringKeyValueInput = page.getByTestId('string-value')
489491
this.jsonKeyValueInput = page.locator('div[data-mode-id=json] textarea')
490492
this.jsonUploadInput = page.getByTestId('upload-input-file')
@@ -1019,7 +1021,11 @@ export class BrowserPage extends BasePage {
10191021
async editListKeyValue(value: string): Promise<void> {
10201022
await this.listElementsList.hover()
10211023
await this.editListButton.click()
1022-
await this.listKeyElementEditorInput.fill(value, {
1024+
1025+
// Wait for any list editor to appear - this is a legacy method
1026+
const editorInput = this.listKeyElementEditorInput.first()
1027+
await expect(editorInput).toBeVisible()
1028+
await editorInput.fill(value, {
10231029
timeout: 0,
10241030
noWaitAfter: false,
10251031
})
@@ -1718,4 +1724,110 @@ export class BrowserPage extends BasePage {
17181724
})
17191725
.toContain(expectedValue)
17201726
}
1727+
async editListElementValue(newValue: string): Promise<void> {
1728+
await this.listElementsList.first().hover()
1729+
await this.editListButton.first().click()
1730+
1731+
// Wait for any list editor to appear - don't assume specific index
1732+
const editorInput = this.listKeyElementEditorInput.first()
1733+
await expect(editorInput).toBeVisible()
1734+
await editorInput.fill(newValue, {
1735+
timeout: 0,
1736+
noWaitAfter: false,
1737+
})
1738+
await this.applyButton.click()
1739+
1740+
// Wait for the editor to close and changes to be applied
1741+
await expect(editorInput).not.toBeVisible()
1742+
1743+
// Wait for the new value to appear in the first list element
1744+
await expect(this.listElementsList.first()).toContainText(newValue)
1745+
}
1746+
1747+
async cancelListElementEdit(newValue: string): Promise<void> {
1748+
await this.listElementsList.first().hover()
1749+
await this.editListButton.first().click()
1750+
1751+
// Wait for any list editor to appear - don't assume specific index
1752+
const editorInput = this.listKeyElementEditorInput.first()
1753+
await expect(editorInput).toBeVisible()
1754+
await editorInput.fill(newValue, {
1755+
timeout: 0,
1756+
noWaitAfter: false,
1757+
})
1758+
1759+
// Cancel using Escape key
1760+
await this.page.keyboard.press('Escape')
1761+
1762+
// Wait for the editor to close
1763+
await expect(editorInput).not.toBeVisible()
1764+
}
1765+
1766+
async addElementsToList(
1767+
elements: string[],
1768+
position: AddElementInList = AddElementInList.Tail,
1769+
): Promise<void> {
1770+
if (await this.toast.isCloseButtonVisible()) {
1771+
await this.toast.closeToast()
1772+
}
1773+
await this.addKeyValueItemsButton.click()
1774+
1775+
if (position === AddElementInList.Head) {
1776+
await this.removeElementFromListSelect.click()
1777+
await this.removeFromHeadSelection.click()
1778+
await expect(this.removeFromHeadSelection).not.toBeVisible()
1779+
}
1780+
1781+
for (let i = 0; i < elements.length; i += 1) {
1782+
await this.getListElementInput(i).click()
1783+
await this.getListElementInput(i).fill(elements[i])
1784+
if (elements.length > 1 && i < elements.length - 1) {
1785+
await this.addAdditionalElement.click()
1786+
}
1787+
}
1788+
await this.saveElementButton.click()
1789+
}
1790+
1791+
async removeListElementsFromTail(count: number): Promise<void> {
1792+
await this.removeElementFromListIconButton.click()
1793+
await this.countInput.fill(count.toString())
1794+
await this.removeElementFromListButton.click()
1795+
await this.confirmRemoveListElementButton.click()
1796+
}
1797+
1798+
async removeListElementsFromHead(count: number): Promise<void> {
1799+
await this.removeElementFromListIconButton.click()
1800+
await this.countInput.fill(count.toString())
1801+
await this.removeElementFromListSelect.click()
1802+
await this.removeFromHeadSelection.click()
1803+
await this.removeElementFromListButton.click()
1804+
await this.confirmRemoveListElementButton.click()
1805+
}
1806+
1807+
async verifyListContainsElements(
1808+
expectedElements: string[],
1809+
): Promise<void> {
1810+
const displayedElements = await this.getAllListElements()
1811+
expectedElements.forEach((expectedElement) => {
1812+
expect(displayedElements).toContain(expectedElement)
1813+
})
1814+
}
1815+
1816+
async verifyListDoesNotContainElements(
1817+
unwantedElements: string[],
1818+
): Promise<void> {
1819+
const displayedElements = await this.getAllListElements()
1820+
unwantedElements.forEach((unwantedElement) => {
1821+
expect(displayedElements).not.toContain(unwantedElement)
1822+
})
1823+
}
1824+
1825+
async waitForListLengthToUpdate(expectedLength: number): Promise<void> {
1826+
await expect
1827+
.poll(async () => {
1828+
const keyLength = await this.getKeyLength()
1829+
return parseInt(keyLength, 10)
1830+
})
1831+
.toBe(expectedLength)
1832+
}
17211833
}
Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
import { faker } from '@faker-js/faker'
2+
3+
import { BrowserPage } from '../../../pageObjects/browser-page'
4+
import { test, expect } from '../../../fixtures/test'
5+
import { ossStandaloneConfig } from '../../../helpers/conf'
6+
import { AddElementInList } from '../../../helpers/constants'
7+
import {
8+
addStandaloneInstanceAndNavigateToIt,
9+
navigateToStandaloneInstance,
10+
} from '../../../helpers/utils'
11+
12+
test.describe('Browser - Edit Key Operations - List Key Editing', () => {
13+
let browserPage: BrowserPage
14+
let keyName: string
15+
let cleanupInstance: () => Promise<void>
16+
17+
test.beforeEach(async ({ page, api: { databaseService } }) => {
18+
browserPage = new BrowserPage(page)
19+
keyName = faker.string.alphanumeric(10)
20+
cleanupInstance = await addStandaloneInstanceAndNavigateToIt(
21+
page,
22+
databaseService,
23+
)
24+
25+
await navigateToStandaloneInstance(page)
26+
})
27+
28+
test.afterEach(async ({ api: { keyService } }) => {
29+
// Clean up: delete the key if it exists
30+
try {
31+
await keyService.deleteKeyByNameApi(
32+
keyName,
33+
ossStandaloneConfig.databaseName,
34+
)
35+
} catch (error) {
36+
// Key might already be deleted in test, ignore error
37+
}
38+
39+
await cleanupInstance()
40+
})
41+
42+
test('should edit list element value successfully', async ({
43+
api: { keyService },
44+
}) => {
45+
// Arrange: Create a list key with multiple elements
46+
const listElements = [
47+
faker.lorem.word(),
48+
faker.lorem.word(),
49+
faker.lorem.word(),
50+
]
51+
const newElementValue = faker.lorem.word()
52+
53+
await keyService.addListKeyApi(
54+
{ keyName, elements: listElements },
55+
ossStandaloneConfig,
56+
)
57+
58+
// Open key details and verify initial content
59+
await browserPage.openKeyDetailsAndVerify(keyName)
60+
await browserPage.verifyListContainsElements(listElements)
61+
await browserPage.verifyKeyLength(listElements.length.toString())
62+
63+
// Edit the first element value
64+
await browserPage.editListElementValue(newElementValue)
65+
66+
// Verify the element was updated
67+
await browserPage.verifyListContainsElements([newElementValue])
68+
await browserPage.verifyListDoesNotContainElements([listElements[0]])
69+
await browserPage.verifyKeyLength(listElements.length.toString()) // Length should remain the same
70+
})
71+
72+
test('should cancel list element edit successfully', async ({
73+
api: { keyService },
74+
}) => {
75+
// Arrange: Create a list key
76+
const listElements = [faker.lorem.word(), faker.lorem.word()]
77+
const attemptedValue = faker.lorem.word()
78+
79+
await keyService.addListKeyApi(
80+
{ keyName, elements: listElements },
81+
ossStandaloneConfig,
82+
)
83+
84+
// Open key details and start edit but cancel
85+
await browserPage.openKeyDetailsAndVerify(keyName)
86+
await browserPage.verifyListContainsElements(listElements)
87+
88+
// Start edit but cancel
89+
await browserPage.cancelListElementEdit(attemptedValue)
90+
91+
// Verify original content is preserved
92+
await browserPage.verifyListContainsElements(listElements)
93+
await browserPage.verifyListDoesNotContainElements([attemptedValue])
94+
})
95+
96+
test('should add elements to list tail successfully', async ({
97+
api: { keyService },
98+
}) => {
99+
// Arrange: Create a list key with initial elements
100+
const initialElements = [faker.lorem.word(), faker.lorem.word()]
101+
const newElements = [faker.lorem.word(), faker.lorem.word()]
102+
103+
await keyService.addListKeyApi(
104+
{ keyName, elements: initialElements },
105+
ossStandaloneConfig,
106+
)
107+
108+
// Open key details and add elements to tail
109+
await browserPage.openKeyDetailsAndVerify(keyName)
110+
await browserPage.verifyListContainsElements(initialElements)
111+
112+
await browserPage.addElementsToList(newElements, AddElementInList.Tail)
113+
114+
// Verify all elements are present and length is updated
115+
const expectedLength = initialElements.length + newElements.length
116+
await browserPage.waitForListLengthToUpdate(expectedLength)
117+
await browserPage.verifyListContainsElements([
118+
...initialElements,
119+
...newElements,
120+
])
121+
})
122+
123+
test('should add elements to list head successfully', async ({
124+
api: { keyService },
125+
}) => {
126+
// Arrange: Create a list key with initial elements
127+
const initialElements = [faker.lorem.word(), faker.lorem.word()]
128+
const newElements = [faker.lorem.word()]
129+
130+
await keyService.addListKeyApi(
131+
{ keyName, elements: initialElements },
132+
ossStandaloneConfig,
133+
)
134+
135+
// Open key details and add elements to head
136+
await browserPage.openKeyDetailsAndVerify(keyName)
137+
await browserPage.verifyListContainsElements(initialElements)
138+
139+
await browserPage.addElementsToList(newElements, AddElementInList.Head)
140+
141+
// Verify all elements are present and length is updated
142+
const expectedLength = initialElements.length + newElements.length
143+
await browserPage.waitForListLengthToUpdate(expectedLength)
144+
await browserPage.verifyListContainsElements([
145+
...newElements,
146+
...initialElements,
147+
])
148+
})
149+
150+
test('should remove elements from list tail successfully', async ({
151+
api: { keyService },
152+
}) => {
153+
// Arrange: Create a list key with multiple elements
154+
const listElements = [
155+
faker.lorem.word(),
156+
faker.lorem.word(),
157+
faker.lorem.word(),
158+
faker.lorem.word(),
159+
]
160+
const removeCount = 2
161+
162+
await keyService.addListKeyApi(
163+
{ keyName, elements: listElements },
164+
ossStandaloneConfig,
165+
)
166+
167+
// Open key details and remove elements from tail
168+
await browserPage.openKeyDetailsAndVerify(keyName)
169+
await browserPage.verifyListContainsElements(listElements)
170+
171+
await browserPage.removeListElementsFromTail(removeCount)
172+
173+
// Verify length is updated (Redis lists remove from the right/tail)
174+
const expectedLength = listElements.length - removeCount
175+
await browserPage.waitForListLengthToUpdate(expectedLength)
176+
await browserPage.verifyKeyLength(expectedLength.toString())
177+
178+
// Verify the correct elements were removed (last 2 elements should be gone)
179+
const remainingElements = listElements.slice(0, -removeCount) // Keep all but last 2
180+
const removedElements = listElements.slice(-removeCount) // Last 2 elements
181+
await browserPage.verifyListContainsElements(remainingElements)
182+
await browserPage.verifyListDoesNotContainElements(removedElements)
183+
})
184+
185+
test('should remove elements from list head successfully', async ({
186+
api: { keyService },
187+
}) => {
188+
// Arrange: Create a list key with multiple elements
189+
const listElements = [
190+
faker.lorem.word(),
191+
faker.lorem.word(),
192+
faker.lorem.word(),
193+
faker.lorem.word(),
194+
]
195+
const removeCount = 1
196+
197+
await keyService.addListKeyApi(
198+
{ keyName, elements: listElements },
199+
ossStandaloneConfig,
200+
)
201+
202+
// Open key details and remove elements from head
203+
await browserPage.openKeyDetailsAndVerify(keyName)
204+
await browserPage.verifyListContainsElements(listElements)
205+
206+
await browserPage.removeListElementsFromHead(removeCount)
207+
208+
// Verify length is updated (Redis lists remove from the left/head)
209+
const expectedLength = listElements.length - removeCount
210+
await browserPage.waitForListLengthToUpdate(expectedLength)
211+
await browserPage.verifyKeyLength(expectedLength.toString())
212+
213+
// Verify the correct elements were removed (first element should be gone)
214+
const remainingElements = listElements.slice(removeCount) // Skip first element
215+
const removedElements = listElements.slice(0, removeCount) // First element
216+
await browserPage.verifyListContainsElements(remainingElements)
217+
await browserPage.verifyListDoesNotContainElements(removedElements)
218+
})
219+
220+
test('should handle removing all elements from list', async ({
221+
api: { keyService },
222+
}) => {
223+
// Arrange: Create a list key with a few elements
224+
const listElements = [faker.lorem.word(), faker.lorem.word()]
225+
226+
await keyService.addListKeyApi(
227+
{ keyName, elements: listElements },
228+
ossStandaloneConfig,
229+
)
230+
231+
// Open key details and remove all elements
232+
await browserPage.openKeyDetailsAndVerify(keyName)
233+
await browserPage.verifyListContainsElements(listElements)
234+
235+
await browserPage.removeListElementsFromTail(listElements.length)
236+
237+
// Verify list is empty (key should be removed when list becomes empty)
238+
await expect
239+
.poll(async () => {
240+
try {
241+
return await browserPage.isKeyDetailsOpen(keyName)
242+
} catch {
243+
return false
244+
}
245+
})
246+
.toBe(false)
247+
})
248+
})

0 commit comments

Comments
 (0)