Skip to content

RI-6570 Verify generic edit operations in the browsers module #4730

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: feature/RI-6570/e2e-playwright-browser-keys-read
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
61 changes: 61 additions & 0 deletions tests/playwright/pageObjects/browser-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1600,4 +1600,65 @@ export class BrowserPage extends BasePage {
await this.verifyKeyTTL(expectedTTL)
await this.closeKeyDetailsAndVerify()
}

async editKeyTTLValue(newTTL: number): Promise<void> {
await this.editKeyTTLButton.click()
await this.editKeyTTLInput.clear()
await this.editKeyTTLInput.fill(newTTL.toString())
await this.applyButton.click()
}

async removeKeyTTL(): Promise<void> {
await this.editKeyTTLButton.click()
await this.editKeyTTLInput.clear()
await this.editKeyTTLInput.fill('') // Explicitly set to empty string
// Don't fill anything - empty field means persistent (-1)
await this.applyButton.click()

// Wait for the TTL to become persistent using the existing helper
await expect
.poll(async () => {
try {
await this.verifyTTLIsPersistent()
return true
} catch {
return false
}
})
.toBe(true)
}

async waitForTTLToUpdate(expectedMinValue: number): Promise<void> {
await expect
.poll(async () => {
const currentTTL = await this.keyDetailsTTL.textContent()
const ttlMatch = currentTTL?.match(/TTL:\s*(\d+)/)
return ttlMatch ? parseInt(ttlMatch[1], 10) : 0
})
.toBeGreaterThan(expectedMinValue)
}

async verifyTTLIsWithinRange(
expectedTTL: number,
marginSeconds = 60,
): Promise<void> {
const displayedTTL = await this.keyDetailsTTL.textContent()
const ttlMatch = displayedTTL?.match(/TTL:\s*(\d+)/)
expect(ttlMatch).toBeTruthy()

const actualTTL = parseInt(ttlMatch![1], 10)
expect(actualTTL).toBeGreaterThan(expectedTTL - marginSeconds)
expect(actualTTL).toBeLessThanOrEqual(expectedTTL)
}

async verifyTTLIsPersistent(): Promise<void> {
const displayedTTL = await this.keyDetailsTTL.textContent()
expect(displayedTTL).toContain('No limit')
}

async verifyTTLIsNotPersistent(): Promise<void> {
const displayedTTL = await this.keyDetailsTTL.textContent()
expect(displayedTTL).toContain('TTL:')
expect(displayedTTL).not.toContain('No limit')
}
}
188 changes: 188 additions & 0 deletions tests/playwright/tests/browser/keys-edit.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
import { faker } from '@faker-js/faker'

import { BrowserPage } from '../../pageObjects/browser-page'
import { test, expect } from '../../fixtures/test'
import { ossStandaloneConfig } from '../../helpers/conf'
import {
addStandaloneInstanceAndNavigateToIt,
navigateToStandaloneInstance,
} from '../../helpers/utils'

test.describe('Browser - Edit Key Operations', () => {
let browserPage: BrowserPage
let keyName: string
let cleanupInstance: () => Promise<void>

test.beforeEach(async ({ page, api: { databaseService } }) => {
browserPage = new BrowserPage(page)
keyName = faker.string.alphanumeric(10)
cleanupInstance = await addStandaloneInstanceAndNavigateToIt(
page,
databaseService,
)

await navigateToStandaloneInstance(page)
})

test.afterEach(async ({ api: { keyService } }) => {
// Clean up: delete the key if it exists
try {
await keyService.deleteKeyByNameApi(
keyName,
ossStandaloneConfig.databaseName,
)
} catch (error) {
// Key might already be deleted in test, ignore error
}

await cleanupInstance()
})

test.describe('Key Name Editing', () => {
test('should edit string key name successfully', async ({
api: { keyService },
}) => {
// Arrange: Create a string key
const keyValue = faker.lorem.words(3)
const newKeyName = `${keyName}_renamed`

await keyService.addStringKeyApi(
{ keyName, value: keyValue },
ossStandaloneConfig,
)

// Open key details
await browserPage.searchByKeyName(keyName)
await browserPage.openKeyDetailsByKeyName(keyName)

// Edit key name
await browserPage.editKeyNameButton.click()
await browserPage.keyNameInput.clear()
await browserPage.keyNameInput.fill(newKeyName)
await browserPage.applyButton.click()

// Verify key name was updated in the details header
await expect
.poll(async () => {
const keyNameText =
await browserPage.keyNameFormDetails.textContent()
return keyNameText
})
.toContain(newKeyName)

// Wait for the key list to update and verify the new key exists
await expect
.poll(async () => {
await browserPage.searchByKeyName(newKeyName)
return browserPage.isKeyIsDisplayedInTheList(newKeyName)
})
.toBe(true)

// Verify the old key name doesn't exist in list
await expect
.poll(async () => {
await browserPage.searchByKeyName(keyName)
return browserPage.isKeyIsDisplayedInTheList(keyName)
})
.toBe(false)

// Update keyName for cleanup
keyName = newKeyName
})

test('should cancel key name edit operation', async ({
api: { keyService },
}) => {
// Arrange: Create a string key
const keyValue = faker.lorem.words(3)
const originalKeyName = keyName
const attemptedNewName = `${keyName}_attempted_rename`

await keyService.addStringKeyApi(
{ keyName, value: keyValue },
ossStandaloneConfig,
)

// Open key details
await browserPage.searchByKeyName(keyName)
await browserPage.openKeyDetailsByKeyName(keyName)

// Verify original key name is displayed
const displayedOriginalName =
await browserPage.keyNameFormDetails.textContent()
expect(displayedOriginalName).toContain(originalKeyName)

// Start editing but cancel
await browserPage.editKeyNameButton.click()
await browserPage.keyNameInput.clear()
await browserPage.keyNameInput.fill(attemptedNewName)

// Cancel the edit by clicking outside the edit area
await browserPage.keyDetailsHeader.click()

// Verify the original key name is still displayed (edit was cancelled)
const displayedNameAfterCancel =
await browserPage.keyNameFormDetails.textContent()
expect(displayedNameAfterCancel).toContain(originalKeyName)
expect(displayedNameAfterCancel).not.toContain(attemptedNewName)

// Verify the original key still exists in the list
await browserPage.searchByKeyName(originalKeyName)
const originalKeyExists =
await browserPage.isKeyIsDisplayedInTheList(originalKeyName)
expect(originalKeyExists).toBe(true)

// Verify the attempted new name doesn't exist
await browserPage.searchByKeyName(attemptedNewName)
const attemptedKeyExists =
await browserPage.isKeyIsDisplayedInTheList(attemptedNewName)
expect(attemptedKeyExists).toBe(false)
})
})

test.describe('TTL Editing', () => {
test('should edit string key TTL successfully', async ({
api: { keyService },
}) => {
// Arrange: Create a string key with TTL
const keyValue = faker.lorem.words(3)
const initialTTL = 3600 // 1 hour
const newTTL = 7200 // 2 hours

await keyService.addStringKeyApi(
{ keyName, value: keyValue, expire: initialTTL },
ossStandaloneConfig,
)

// Open key details and verify initial TTL
await browserPage.openKeyDetailsAndVerify(keyName)
await browserPage.verifyTTLIsNotPersistent()

// Edit the TTL and verify update
await browserPage.editKeyTTLValue(newTTL)
await browserPage.waitForTTLToUpdate(initialTTL)
await browserPage.verifyTTLIsWithinRange(newTTL)
})

test('should remove TTL from string key (set to persistent)', async ({
api: { keyService },
}) => {
// Arrange: Create a string key with TTL
const keyValue = faker.lorem.words(3)
const initialTTL = 3600 // 1 hour

await keyService.addStringKeyApi(
{ keyName, value: keyValue, expire: initialTTL },
ossStandaloneConfig,
)

// Open key details and verify initial TTL
await browserPage.openKeyDetailsAndVerify(keyName)
await browserPage.verifyTTLIsNotPersistent()

// Remove TTL and verify it becomes persistent
await browserPage.removeKeyTTL()
await browserPage.verifyTTLIsPersistent()
})
})
})
Loading