rabbitmq-server/selenium/test/pageobjects/BasePage.js

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

378 lines
12 KiB
JavaScript
Raw Normal View History

const { By, Key, until, Builder, Select, WebDriverError, NoSuchSessionError } = require('selenium-webdriver')
const MENU_TABS = By.css('div#menu ul#tabs')
const USER = By.css('li#logout')
const LOGOUT_FORM = By.css('li#logout form')
const SELECT_VHOSTS = By.css('select#show-vhost')
2024-05-14 17:59:36 +08:00
const SELECT_REFRESH = By.css('ul#topnav li#interval select#update-every')
const OVERVIEW_TAB = By.css('div#menu ul#tabs li#overview')
const CONNECTIONS_TAB = By.css('div#menu ul#tabs li#connections')
const CHANNELS_TAB = By.css('div#menu ul#tabs li#channels')
const QUEUES_AND_STREAMS_TAB = By.css('div#menu ul#tabs li#queues-and-streams')
const EXCHANGES_TAB = By.css('div#menu ul#tabs li#exchanges')
const ADMIN_TAB = By.css('div#menu ul#tabs li#admin')
2023-06-11 03:21:32 +08:00
const STREAM_CONNECTIONS_TAB = By.css('div#menu ul#tabs li#stream-connections')
const FORM_POPUP_WARNING = By.css('div.form-popup-warn')
const FORM_POPUP_WARNING_CLOSE_BUTTON = By.css('div.form-popup-warn span#close')
const FORM_POPUP_OPTIONS = By.css('div.form-popup-options')
const ADD_MINUS_BUTTON = By.css('div#main table.list thead tr th.plus-minus')
const TABLE_COLUMNS_POPUP = By.css('div.form-popup-options table.form')
const FORM_POPUP_OPTIONS_CLOSE_BUTTON = By.css('div.form-popup-options span#close')
module.exports = class BasePage {
driver
timeout
polling
2024-05-24 22:44:21 +08:00
interactionDelay
constructor (webdriver) {
this.driver = webdriver
2024-01-03 16:28:36 +08:00
this.timeout = parseInt(process.env.SELENIUM_TIMEOUT) || 1000 // max time waiting to locate an element. Should be less that test timeout
this.polling = parseInt(process.env.SELENIUM_POLLING) || 500 // how frequent selenium searches for an element
2024-05-24 22:44:21 +08:00
this.interactionDelay = parseInt(process.env.SELENIUM_INTERACTION_DELAY) || 0 // slow down interactions (when rabbit is behind a http proxy)
}
async isLoaded () {
return this.waitForDisplayed(MENU_TABS)
}
async logout () {
await this.submit(LOGOUT_FORM)
}
async getUser () {
return this.getText(USER)
}
2024-05-14 17:59:36 +08:00
async selectRefreshOption(option) {
return this.selectOption(SELECT_REFRESH, option)
}
async waitForOverviewTab() {
await this.driver.sleep(250)
return this.waitForDisplayed(OVERVIEW_TAB)
}
async clickOnOverviewTab () {
return this.click(CONNECTIONS_TAB)
}
async clickOnConnectionsTab () {
return this.click(CONNECTIONS_TAB)
}
async waitForConnectionsTab() {
await this.driver.sleep(250)
return this.waitForDisplayed(CONNECTIONS_TAB)
}
2024-06-04 04:44:47 +08:00
async clickOnAdminTab () {
return this.click(ADMIN_TAB)
}
2024-06-04 04:44:47 +08:00
async waitForAdminTab() {
await this.driver.sleep(250)
return this.waitForDisplayed(ADMIN_TAB)
}
async clickOnChannelsTab () {
return this.click(CHANNELS_TAB)
}
async waitForChannelsTab() {
await this.driver.sleep(250)
return this.waitForDisplayed(CHANNELS_TAB)
}
async clickOnExchangesTab () {
return this.click(EXCHANGES_TAB)
}
2024-06-04 04:44:47 +08:00
async waitForExchangesTab() {
await this.driver.sleep(250)
return this.waitForDisplayed(EXCHANGES_TAB)
}
async clickOnQueuesTab () {
return this.click(QUEUES_AND_STREAMS_TAB)
}
async waitForQueuesTab() {
2024-05-24 22:44:21 +08:00
await this.driver.sleep(250)
return this.waitForDisplayed(QUEUES_AND_STREAMS_TAB)
}
async clickOnStreamTab () {
return this.click(STREAM_CONNECTIONS_TAB)
}
2023-06-11 03:21:32 +08:00
async waitForStreamConnectionsTab() {
return this.waitForDisplayed(STREAM_CONNECTIONS_TAB)
}
2024-01-03 16:28:36 +08:00
async getSelectableOptions(locator) {
let selectable = await this.waitForDisplayed(locator)
const select = await new Select(selectable)
const optionList = await select.getOptions()
let table_model = []
2024-01-03 16:28:36 +08:00
for (const index in optionList) {
const t = await optionList[index].getText()
const v = await optionList[index].getAttribute('value')
table_model.push({"text":t, "value": v})
}
2024-01-03 16:28:36 +08:00
return table_model
}
2024-01-03 16:28:36 +08:00
async selectOption(locator, text) {
let selectable = await this.waitForDisplayed(locator)
const select = await new Select(selectable)
return select.selectByVisibleText(text)
}
async selectOptionByValue(locator, value) {
let selectable = await this.waitForDisplayed(locator)
const select = await new Select(selectable)
return select.selectByValue(value)
}
2024-01-03 16:28:36 +08:00
async getSelectableVhosts() {
2024-02-10 00:22:17 +08:00
const table_model = await this.getSelectableOptions(SELECT_VHOSTS)
2024-01-03 16:28:36 +08:00
let new_table_model = []
for (let i = 0; i < table_model.length; i++) {
new_table_model.push(await table_model[i].text)
}
return new_table_model
}
2024-11-18 17:23:21 +08:00
async getTable(tableLocator, firstNColumns, rowClass) {
const table = await this.waitForDisplayed(tableLocator)
const rows = await table.findElements(rowClass == undefined ?
By.css('tbody tr') : By.css('tbody tr.' + rowClass))
let table_model = []
for (let row of rows) {
let columns = await row.findElements(By.css('td'))
let table_row = []
for (let column of columns) {
if (firstNColumns == undefined || table_row.length < firstNColumns) {
table_row.push(await column.getText())
}
}
table_model.push(table_row)
}
return table_model
}
async isPopupWarningDisplayed() {
try {
let element = await driver.findElement(FORM_POPUP_WARNING)
return element.isDisplayed()
} catch(e) {
return Promise.resolve(false)
}
/*
let element = await driver.findElement(FORM_POPUP)
return this.driver.wait(until.elementIsVisible(element), this.timeout / 2,
'Timed out after [timeout=' + this.timeout + ';polling=' + this.polling + '] awaiting till visible ' + element,
this.polling / 2).then(function onWarningVisible(e) {
return Promise.resolve(true)
}, function onError(e) {
return Promise.resolve(false)
})
*/
}
async isPopupWarningNotDisplayed() {
return this.isElementNotVisible(FORM_POPUP_WARNING)
}
async isElementNotVisible(locator) {
try {
await this.driver.wait(async() => {
try {
const element = await this.driver.findElement(locator)
const visible = await element.isDisplayed()
return !visible
} catch (error) {
return true
}
}, this.timeout)
return true
} catch (error) {
return false
}
}
async getPopupWarning() {
let element = await driver.findElement(FORM_POPUP_WARNING)
return this.driver.wait(until.elementIsVisible(element), this.timeout,
'Timed out after [timeout=' + this.timeout + ';polling=' + this.polling + '] awaiting till visible ' + element,
this.polling).getText().then((value) => value.substring(0, value.search('\n\nClose')))
}
async closePopupWarning() {
return this.click(FORM_POPUP_WARNING_CLOSE_BUTTON)
}
async clickOnSelectTableColumns() {
return this.click(ADD_MINUS_BUTTON)
}
async getSelectableTableColumns() {
const table = await this.waitForDisplayed(TABLE_COLUMNS_POPUP)
const rows = await table.findElements(By.css('tbody tr'))
let table_model = []
for (let i = 1; i < rows.length; i++) { // skip first row
let groupNameLabel = await rows[i].findElement(By.css('th label'))
let groupName = await groupNameLabel.getText()
let columns = await rows[i].findElements(By.css('td label'))
let table_row = []
for (let column of columns) {
let checkbox = await column.findElement(By.css('input'))
table_row.push({"name:" : await column.getText(), "id" : await checkbox.getAttribute("id")})
}
let group = {"name": groupName, "columns": table_row}
table_model.push(group)
}
return table_model
}
async selectTableColumnsById(arrayOfColumnsIds) {
await this.clickOnSelectTableColumns()
const table = await this.waitForDisplayed(TABLE_COLUMNS_POPUP)
for (let id of arrayOfColumnsIds) {
let checkbox = await table.findElement(By.css('tbody tr input#'+id))
await checkbox.click()
}
await this.click(FORM_POPUP_OPTIONS_CLOSE_BUTTON)
}
async isDisplayed(locator) {
2024-01-28 19:02:15 +08:00
try {
let element = await driver.findElement(locator)
2024-05-24 22:44:21 +08:00
return this.driver.wait(until.elementIsVisible(element), this.timeout,
2024-01-28 19:02:15 +08:00
'Timed out after [timeout=' + this.timeout + ';polling=' + this.polling + '] awaiting till visible ' + element,
this.polling / 2)
}catch(error) {
return Promise.resolve(false)
}
}
async waitForLocated (locator) {
let attempts = 3
let retry = false
let rethrowError = null
do {
try {
return this.driver.wait(until.elementLocated(locator), this.timeout,
'Timed out after [timeout=' + this.timeout + ';polling=' + this.polling + '] seconds locating ' + locator,
this.polling)
}catch(error) {
if (error.name.includes("StaleElementReferenceError")) {
retry = true
}else if (!error.name.includes("NoSuchSessionError")) {
console.error("Failed waitForLocated " + locator + " due to " + error)
retry = false
}
rethrowError = error
}
} while (retry && --attempts > 0)
throw rethrowError
}
async waitForVisible (element) {
let attempts = 3
let retry = false
let rethrowError = null
do {
try {
return this.driver.wait(until.elementIsVisible(element), this.timeout,
'Timed out after [timeout=' + this.timeout + ';polling=' + this.polling + '] awaiting till visible ' + element,
this.polling)
}catch(error) {
if (error.name.includes("StaleElementReferenceError")) {
retry = true
}else if (!error.name.includes("NoSuchSessionError")) {
console.error("Failed to find visible element " + element + " due to " + error)
retry = false
}
rethrowError = error
}
} while (retry && --attempts > 0)
throw rethrowError
}
2024-01-28 19:02:15 +08:00
async waitForDisplayed (locator) {
let attempts = 3
let retry = false
let rethrowError = null
do {
if (this.interactionDelay && this.interactionDelay > 0) await this.driver.sleep(this.interactionDelay)
try {
return this.waitForVisible(await this.waitForLocated(locator))
}catch(error) {
if (error.name.includes("StaleElementReferenceError")) {
retry = true
}else if (!error.name.includes("NoSuchSessionError")) {
retry = false
console.error("Failed to waitForDisplayed " + locator + " due to " + error)
}
rethrowError = error
}
} while (retry && --attempts > 0 )
throw rethrowError
}
async getText (locator) {
const element = await this.waitForDisplayed(locator)
return element.getText()
}
async getValue (locator) {
const element = await this.waitForDisplayed(locator)
return element.getAttribute('value')
}
async click (locator) {
2024-05-24 22:44:21 +08:00
if (this.interactionDelay) await this.driver.sleep(this.interactionDelay)
const element = await this.waitForDisplayed(locator)
try {
return element.click()
} catch(error) {
console.error("Failed to click on " + locator + " due to " + error);
throw error;
}
}
async submit (locator) {
const element = await this.waitForDisplayed(locator)
return element.submit()
}
async sendKeys (locator, keys) {
const element = await this.waitForDisplayed(locator)
await element.click()
await element.clear()
return element.sendKeys(keys)
}
async chooseFile (locator, file) {
const element = await this.waitForDisplayed(locator)
2024-02-10 00:22:17 +08:00
const remote = require('selenium-webdriver/remote');
driver.setFileDetector(new remote.FileDetector);
return element.sendKeys(file)
}
async acceptAlert () {
await this.driver.wait(until.alertIsPresent(), this.timeout);
await this.driver.sleep(250)
2024-02-10 00:22:17 +08:00
const alert = await this.driver.switchTo().alert();
await this.driver.sleep(250)
return alert.accept();
}
log(message) {
console.log(new Date() + " " + message)
}
capture () {
this.driver.takeScreenshot().then(
function (image) {
require('fs').writeFileSync('/tmp/capture.png', image, 'base64')
}
)
}
}