Skip to content

Commit fd8c54e

Browse files
committed
test: verify edit operation for json key value in browsers module
* added e2e test to verify whether the edit key value functionality is working fine for the json type in the browser module re #RI-6570
1 parent 76052ac commit fd8c54e

File tree

2 files changed

+433
-0
lines changed

2 files changed

+433
-0
lines changed

tests/playwright/pageObjects/browser-page.ts

Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1600,4 +1600,242 @@ export class BrowserPage extends BasePage {
16001600
await this.verifyKeyTTL(expectedTTL)
16011601
await this.closeKeyDetailsAndVerify()
16021602
}
1603+
1604+
async editJsonProperty(
1605+
propertyKey: string,
1606+
newValue: string | number | boolean,
1607+
): Promise<void> {
1608+
// TODO: Ideally this should find by property key, but the current DOM structure
1609+
// makes it complex to navigate from key to value reliably. For now, we use the
1610+
// working approach of finding by current value.
1611+
const currentValue = await this.getJsonPropertyValue(propertyKey)
1612+
if (!currentValue) {
1613+
throw new Error(`Property "${propertyKey}" not found`)
1614+
}
1615+
1616+
// Find and click the value element
1617+
const valueElement = this.page
1618+
.getByTestId('json-scalar-value')
1619+
.filter({ hasText: currentValue })
1620+
.first()
1621+
1622+
await valueElement.click()
1623+
await expect(this.inlineItemEditor).toBeVisible()
1624+
1625+
// Format and apply the new value
1626+
const formattedValue =
1627+
typeof newValue === 'string' ? `"${newValue}"` : newValue.toString()
1628+
1629+
await this.inlineItemEditor.clear()
1630+
await this.inlineItemEditor.fill(formattedValue)
1631+
await this.applyButton.click()
1632+
await expect(this.inlineItemEditor).not.toBeVisible()
1633+
1634+
if (await this.toast.isCloseButtonVisible()) {
1635+
await this.toast.closeToast()
1636+
}
1637+
}
1638+
1639+
// Convenience methods that use the generic editJsonProperty method
1640+
async editJsonString(propertyKey: string, newValue: string): Promise<void> {
1641+
await this.editJsonProperty(propertyKey, newValue)
1642+
}
1643+
1644+
async editJsonNumber(propertyKey: string, newValue: number): Promise<void> {
1645+
await this.editJsonProperty(propertyKey, newValue)
1646+
}
1647+
1648+
async editJsonBoolean(
1649+
propertyKey: string,
1650+
newValue: boolean,
1651+
): Promise<void> {
1652+
await this.editJsonProperty(propertyKey, newValue)
1653+
}
1654+
1655+
async addJsonProperty(
1656+
key: string,
1657+
value: string | number | boolean,
1658+
): Promise<void> {
1659+
// For JSON objects, add a new property at the same level
1660+
await this.addJsonObjectButton.click()
1661+
1662+
// Wait for the form to appear
1663+
await expect(this.jsonKeyInput).toBeVisible()
1664+
await expect(this.jsonValueInput).toBeVisible()
1665+
1666+
// Format the key and value properly for JSON
1667+
const formattedKey = `"${key}"`
1668+
let formattedValue: string
1669+
if (typeof value === 'string') {
1670+
formattedValue = `"${value}"`
1671+
} else {
1672+
formattedValue = value.toString()
1673+
}
1674+
1675+
// Fill the key and value
1676+
await this.jsonKeyInput.clear()
1677+
await this.jsonKeyInput.fill(formattedKey)
1678+
await this.jsonValueInput.clear()
1679+
await this.jsonValueInput.fill(formattedValue)
1680+
1681+
// Apply the changes
1682+
await this.applyButton.click()
1683+
1684+
// Wait for the form to disappear
1685+
await expect(this.jsonKeyInput).not.toBeVisible()
1686+
1687+
// Close any success toast if it appears
1688+
if (await this.toast.isCloseButtonVisible()) {
1689+
await this.toast.closeToast()
1690+
}
1691+
}
1692+
1693+
async editEntireJsonStructure(newJsonStructure: string): Promise<void> {
1694+
// Switch to Monaco editor
1695+
await this.page
1696+
.getByRole('button', { name: 'Change editor type' })
1697+
.click()
1698+
1699+
// Wait for Monaco editor
1700+
const monacoContainer = this.page.getByTestId('monaco-editor-json-data')
1701+
await expect(monacoContainer).toBeVisible()
1702+
1703+
// Clear and set new JSON content
1704+
const textarea = monacoContainer.locator('textarea').first()
1705+
await textarea.focus()
1706+
await this.page.keyboard.press('Control+A')
1707+
await this.page.keyboard.press('Delete')
1708+
await textarea.type(newJsonStructure)
1709+
1710+
// Wait for button to be enabled and click it
1711+
const updateButton = this.page.getByTestId('json-data-update-btn')
1712+
await expect(updateButton).toBeEnabled()
1713+
await updateButton.click()
1714+
1715+
// Close editor and return to tree view
1716+
const cancelButton = this.page.getByTestId('json-data-cancel-btn')
1717+
if (await cancelButton.isVisible()) {
1718+
await cancelButton.click()
1719+
}
1720+
1721+
if (await this.toast.isCloseButtonVisible()) {
1722+
await this.toast.closeToast()
1723+
}
1724+
}
1725+
1726+
async verifyJsonPropertyExists(key: string, value: string): Promise<void> {
1727+
// Expand all objects and get the actual value
1728+
const actualValue = await this.getJsonPropertyValue(key)
1729+
expect(actualValue).toBe(value)
1730+
}
1731+
1732+
async verifyJsonPropertyNotExists(key: string): Promise<void> {
1733+
const actualValue = await this.getJsonPropertyValue(key)
1734+
expect(actualValue).toBeNull()
1735+
}
1736+
1737+
async waitForJsonDetailsToBeVisible(): Promise<void> {
1738+
await expect(this.page.getByTestId('json-details')).toBeVisible()
1739+
}
1740+
1741+
async waitForJsonPropertyUpdate(
1742+
key: string,
1743+
expectedValue: string,
1744+
): Promise<void> {
1745+
await expect
1746+
.poll(async () => {
1747+
try {
1748+
const actualValue = await this.getJsonPropertyValue(key)
1749+
return actualValue === expectedValue
1750+
} catch (error) {
1751+
return false
1752+
}
1753+
})
1754+
.toBe(true)
1755+
}
1756+
1757+
async expandAllJsonObjects(): Promise<void> {
1758+
// Keep expanding until no more expand buttons exist
1759+
while (true) {
1760+
const expandButtons = this.page.getByTestId('expand-object')
1761+
const count = await expandButtons.count()
1762+
1763+
if (count === 0) {
1764+
break // No more expand buttons to click
1765+
}
1766+
1767+
// Click ALL visible expand buttons in this iteration
1768+
const buttons = await expandButtons.all()
1769+
for (const button of buttons) {
1770+
if (await button.isVisible()) {
1771+
await button.click()
1772+
}
1773+
}
1774+
1775+
// Wait for DOM to be ready before checking for new buttons
1776+
await this.page.waitForLoadState('domcontentloaded')
1777+
}
1778+
}
1779+
1780+
async getJsonPropertyValue(propertyName: string): Promise<string | null> {
1781+
// Expand all objects to make sure we can see the property
1782+
await this.expandAllJsonObjects()
1783+
1784+
// Get the JSON content and look for the property with a simple approach
1785+
const jsonContent = await this.jsonKeyValue.textContent()
1786+
if (!jsonContent) return null
1787+
1788+
// Use a more precise regex pattern for different value types
1789+
// Try patterns for strings, numbers, and booleans
1790+
const patterns = [
1791+
new RegExp(`${propertyName}:"([^"]*)"`, 'g'), // String values: name:"value"
1792+
new RegExp(`${propertyName}:(\\d+(?:\\.\\d+)?)`, 'g'), // Number values: age:25
1793+
new RegExp(`${propertyName}:(true|false)`, 'g'), // Boolean values: active:true
1794+
]
1795+
1796+
for (const pattern of patterns) {
1797+
pattern.lastIndex = 0 // Reset regex state
1798+
const match = pattern.exec(jsonContent)
1799+
if (match && match[1]) {
1800+
return match[1]
1801+
}
1802+
}
1803+
1804+
return null
1805+
}
1806+
1807+
async verifyJsonStructureValid(): Promise<void> {
1808+
// Check that no JSON error is displayed
1809+
await expect(this.jsonError).not.toBeVisible()
1810+
1811+
// Check that the JSON data container is visible
1812+
await expect(this.jsonKeyValue).toBeVisible()
1813+
}
1814+
1815+
async cancelJsonScalarValueEdit(propertyKey: string): Promise<void> {
1816+
// Store original value, start editing, then cancel
1817+
const originalValue = await this.getJsonPropertyValue(propertyKey)
1818+
if (!originalValue) {
1819+
throw new Error(`Property "${propertyKey}" not found`)
1820+
}
1821+
1822+
await this.expandAllJsonObjects()
1823+
1824+
// Find the element containing this value
1825+
const targetElement = this.page
1826+
.getByTestId('json-scalar-value')
1827+
.filter({ hasText: originalValue })
1828+
.first()
1829+
1830+
// Start edit, make change, then cancel
1831+
await targetElement.click()
1832+
await expect(this.inlineItemEditor).toBeVisible()
1833+
await this.inlineItemEditor.fill('"canceled_value"')
1834+
await this.page.keyboard.press('Escape')
1835+
await expect(this.inlineItemEditor).not.toBeVisible()
1836+
1837+
// Verify no change occurred
1838+
const finalValue = await this.getJsonPropertyValue(propertyKey)
1839+
expect(finalValue).toBe(originalValue)
1840+
}
16031841
}

0 commit comments

Comments
 (0)