Skip to content

Commit b4cd7fd

Browse files
authored
RI-6570 Verify edit json keys operations for in the browsers module (#4735)
* 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 5211755 commit b4cd7fd

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
@@ -2442,4 +2442,242 @@ export class BrowserPage extends BasePage {
24422442
this.page.locator(`[data-testid="hash-field-${fieldName}"]`),
24432443
).not.toBeVisible()
24442444
}
2445+
2446+
async editJsonProperty(
2447+
propertyKey: string,
2448+
newValue: string | number | boolean,
2449+
): Promise<void> {
2450+
// TODO: Ideally this should find by property key, but the current DOM structure
2451+
// makes it complex to navigate from key to value reliably. For now, we use the
2452+
// working approach of finding by current value.
2453+
const currentValue = await this.getJsonPropertyValue(propertyKey)
2454+
if (!currentValue) {
2455+
throw new Error(`Property "${propertyKey}" not found`)
2456+
}
2457+
2458+
// Find and click the value element
2459+
const valueElement = this.page
2460+
.getByTestId('json-scalar-value')
2461+
.filter({ hasText: currentValue })
2462+
.first()
2463+
2464+
await valueElement.click()
2465+
await expect(this.inlineItemEditor).toBeVisible()
2466+
2467+
// Format and apply the new value
2468+
const formattedValue =
2469+
typeof newValue === 'string' ? `"${newValue}"` : newValue.toString()
2470+
2471+
await this.inlineItemEditor.clear()
2472+
await this.inlineItemEditor.fill(formattedValue)
2473+
await this.applyButton.click()
2474+
await expect(this.inlineItemEditor).not.toBeVisible()
2475+
2476+
if (await this.toast.isCloseButtonVisible()) {
2477+
await this.toast.closeToast()
2478+
}
2479+
}
2480+
2481+
// Convenience methods that use the generic editJsonProperty method
2482+
async editJsonString(propertyKey: string, newValue: string): Promise<void> {
2483+
await this.editJsonProperty(propertyKey, newValue)
2484+
}
2485+
2486+
async editJsonNumber(propertyKey: string, newValue: number): Promise<void> {
2487+
await this.editJsonProperty(propertyKey, newValue)
2488+
}
2489+
2490+
async editJsonBoolean(
2491+
propertyKey: string,
2492+
newValue: boolean,
2493+
): Promise<void> {
2494+
await this.editJsonProperty(propertyKey, newValue)
2495+
}
2496+
2497+
async addJsonProperty(
2498+
key: string,
2499+
value: string | number | boolean,
2500+
): Promise<void> {
2501+
// For JSON objects, add a new property at the same level
2502+
await this.addJsonObjectButton.click()
2503+
2504+
// Wait for the form to appear
2505+
await expect(this.jsonKeyInput).toBeVisible()
2506+
await expect(this.jsonValueInput).toBeVisible()
2507+
2508+
// Format the key and value properly for JSON
2509+
const formattedKey = `"${key}"`
2510+
let formattedValue: string
2511+
if (typeof value === 'string') {
2512+
formattedValue = `"${value}"`
2513+
} else {
2514+
formattedValue = value.toString()
2515+
}
2516+
2517+
// Fill the key and value
2518+
await this.jsonKeyInput.clear()
2519+
await this.jsonKeyInput.fill(formattedKey)
2520+
await this.jsonValueInput.clear()
2521+
await this.jsonValueInput.fill(formattedValue)
2522+
2523+
// Apply the changes
2524+
await this.applyButton.click()
2525+
2526+
// Wait for the form to disappear
2527+
await expect(this.jsonKeyInput).not.toBeVisible()
2528+
2529+
// Close any success toast if it appears
2530+
if (await this.toast.isCloseButtonVisible()) {
2531+
await this.toast.closeToast()
2532+
}
2533+
}
2534+
2535+
async editEntireJsonStructure(newJsonStructure: string): Promise<void> {
2536+
// Switch to Monaco editor
2537+
await this.page
2538+
.getByRole('button', { name: 'Change editor type' })
2539+
.click()
2540+
2541+
// Wait for Monaco editor
2542+
const monacoContainer = this.page.getByTestId('monaco-editor-json-data')
2543+
await expect(monacoContainer).toBeVisible()
2544+
2545+
// Clear and set new JSON content
2546+
const textarea = monacoContainer.locator('textarea').first()
2547+
await textarea.focus()
2548+
await this.page.keyboard.press('Control+A')
2549+
await this.page.keyboard.press('Delete')
2550+
await textarea.type(newJsonStructure)
2551+
2552+
// Wait for button to be enabled and click it
2553+
const updateButton = this.page.getByTestId('json-data-update-btn')
2554+
await expect(updateButton).toBeEnabled()
2555+
await updateButton.click()
2556+
2557+
// Close editor and return to tree view
2558+
const cancelButton = this.page.getByTestId('json-data-cancel-btn')
2559+
if (await cancelButton.isVisible()) {
2560+
await cancelButton.click()
2561+
}
2562+
2563+
if (await this.toast.isCloseButtonVisible()) {
2564+
await this.toast.closeToast()
2565+
}
2566+
}
2567+
2568+
async verifyJsonPropertyExists(key: string, value: string): Promise<void> {
2569+
// Expand all objects and get the actual value
2570+
const actualValue = await this.getJsonPropertyValue(key)
2571+
expect(actualValue).toBe(value)
2572+
}
2573+
2574+
async verifyJsonPropertyNotExists(key: string): Promise<void> {
2575+
const actualValue = await this.getJsonPropertyValue(key)
2576+
expect(actualValue).toBeNull()
2577+
}
2578+
2579+
async waitForJsonDetailsToBeVisible(): Promise<void> {
2580+
await expect(this.page.getByTestId('json-details')).toBeVisible()
2581+
}
2582+
2583+
async waitForJsonPropertyUpdate(
2584+
key: string,
2585+
expectedValue: string,
2586+
): Promise<void> {
2587+
await expect
2588+
.poll(async () => {
2589+
try {
2590+
const actualValue = await this.getJsonPropertyValue(key)
2591+
return actualValue === expectedValue
2592+
} catch (error) {
2593+
return false
2594+
}
2595+
})
2596+
.toBe(true)
2597+
}
2598+
2599+
async expandAllJsonObjects(): Promise<void> {
2600+
// Keep expanding until no more expand buttons exist
2601+
while (true) {
2602+
const expandButtons = this.page.getByTestId('expand-object')
2603+
const count = await expandButtons.count()
2604+
2605+
if (count === 0) {
2606+
break // No more expand buttons to click
2607+
}
2608+
2609+
// Click ALL visible expand buttons in this iteration
2610+
const buttons = await expandButtons.all()
2611+
for (const button of buttons) {
2612+
if (await button.isVisible()) {
2613+
await button.click()
2614+
}
2615+
}
2616+
2617+
// Wait for DOM to be ready before checking for new buttons
2618+
await this.page.waitForLoadState('domcontentloaded')
2619+
}
2620+
}
2621+
2622+
async getJsonPropertyValue(propertyName: string): Promise<string | null> {
2623+
// Expand all objects to make sure we can see the property
2624+
await this.expandAllJsonObjects()
2625+
2626+
// Get the JSON content and look for the property with a simple approach
2627+
const jsonContent = await this.jsonKeyValue.textContent()
2628+
if (!jsonContent) return null
2629+
2630+
// Use a more precise regex pattern for different value types
2631+
// Try patterns for strings, numbers, and booleans
2632+
const patterns = [
2633+
new RegExp(`${propertyName}:"([^"]*)"`, 'g'), // String values: name:"value"
2634+
new RegExp(`${propertyName}:(\\d+(?:\\.\\d+)?)`, 'g'), // Number values: age:25
2635+
new RegExp(`${propertyName}:(true|false)`, 'g'), // Boolean values: active:true
2636+
]
2637+
2638+
for (const pattern of patterns) {
2639+
pattern.lastIndex = 0 // Reset regex state
2640+
const match = pattern.exec(jsonContent)
2641+
if (match && match[1]) {
2642+
return match[1]
2643+
}
2644+
}
2645+
2646+
return null
2647+
}
2648+
2649+
async verifyJsonStructureValid(): Promise<void> {
2650+
// Check that no JSON error is displayed
2651+
await expect(this.jsonError).not.toBeVisible()
2652+
2653+
// Check that the JSON data container is visible
2654+
await expect(this.jsonKeyValue).toBeVisible()
2655+
}
2656+
2657+
async cancelJsonScalarValueEdit(propertyKey: string): Promise<void> {
2658+
// Store original value, start editing, then cancel
2659+
const originalValue = await this.getJsonPropertyValue(propertyKey)
2660+
if (!originalValue) {
2661+
throw new Error(`Property "${propertyKey}" not found`)
2662+
}
2663+
2664+
await this.expandAllJsonObjects()
2665+
2666+
// Find the element containing this value
2667+
const targetElement = this.page
2668+
.getByTestId('json-scalar-value')
2669+
.filter({ hasText: originalValue })
2670+
.first()
2671+
2672+
// Start edit, make change, then cancel
2673+
await targetElement.click()
2674+
await expect(this.inlineItemEditor).toBeVisible()
2675+
await this.inlineItemEditor.fill('"canceled_value"')
2676+
await this.page.keyboard.press('Escape')
2677+
await expect(this.inlineItemEditor).not.toBeVisible()
2678+
2679+
// Verify no change occurred
2680+
const finalValue = await this.getJsonPropertyValue(propertyKey)
2681+
expect(finalValue).toBe(originalValue)
2682+
}
24452683
}

0 commit comments

Comments
 (0)