UNPKG

browsertime

Version:

Get performance metrics from your web page using Browsertime.

244 lines (234 loc) 7.36 kB
import webdriver, { By } from 'selenium-webdriver'; import { getLogger } from '@sitespeed.io/log'; import { executeCommand } from './commandHelper.js'; import { parseSelector } from './selectorParser.js'; const log = getLogger('browsertime.command.addText'); /** * Provides functionality to add text to elements on a web page using various selectors. * @class * @hideconstructor */ export class AddText { constructor(browser, options) { /** * @private */ this.browser = browser; /** * @private */ this.options = options; } /** * @private */ async _waitForElement(driver, locator) { const timeout = this.options?.timeouts?.elementWait ?? 0; if (timeout > 0) { await driver.wait(webdriver.until.elementLocated(locator), timeout); } } /** * @private */ async _getUrl() { try { return ` on ${await this.browser.getDriver().getCurrentUrl()}`; } catch { return ''; } } /** * Adds text to an element using a unified selector string. * Supports CSS selectors (default), and prefix-based strategies: * 'id:myId', 'xpath://input', 'name:email', 'class:input-field'. * * @async * @param {string} selector - The selector string. CSS by default, or use a prefix. * @param {string} text - The text string to add. * @returns {Promise<void>} A promise that resolves when the text has been added. * @throws {Error} Throws an error if the element is not found. */ async run(selector, text) { const { locator, description } = parseSelector(selector); return executeCommand( log, 'Could not add text %s to %s', description, async () => { const driver = this.browser.getDriver(); await this._waitForElement(driver, locator); const element = await driver.findElement(locator); await element.clear(); return element.sendKeys(text); }, this.browser ); } /** * Adds text to an element identified by its ID. * * @async * @private * @example commands.addText.byId('mytext', 'id'); * @param {string} text - The text string to add. * @param {string} id - The ID of the element. * @returns {Promise<void>} A promise that resolves when the text has been added. * @throws {Error} Throws an error if the element is not found. */ async byId(text, id) { const driver = this.browser.getDriver(); try { const locator = By.id(id); await this._waitForElement(driver, locator); const element = await driver.findElement(locator); // make sure we clear it await element.clear(); return element.sendKeys(text); } catch (error) { const url = await this._getUrl(); log.error( 'Could not add text %s to id %s error:%s', text, id, error.message ); log.verbose(error); throw new Error(`Could not add text ${text} to id ${id}${url}`); } } /** * Adds text to an element identified by its XPath. * * @async * @private * @example commands.addText.byXpath('mytext', 'xpath'); * @param {string} text - The text string to add. * @param {string} xpath - The XPath of the element. * @returns {Promise<void>} A promise that resolves when the text has been added. * @throws {Error} Throws an error if the element is not found. */ async byXpath(text, xpath) { const driver = this.browser.getDriver(); try { const locator = By.xpath(xpath); await this._waitForElement(driver, locator); const element = await driver.findElement(locator); // make sure we clear it await element.clear(); return element.sendKeys(text); } catch (error) { const url = await this._getUrl(); log.error( 'Could not add text %s to xpath %s error: %s', text, xpath, error.message ); log.verbose(error); throw new Error(`Could not add text ${text} to xpath ${xpath}${url}`); } } /** * Adds text to an element identified by its CSS selector. * * @async * @private * @example commands.addText.bySelector('mytext', 'selector'); * @param {string} text - The text string to add. * @param {string} selector - The CSS selector of the element. * @returns {Promise<void>} A promise that resolves when the text has been added. * @throws {Error} Throws an error if the element is not found. */ async bySelector(text, selector) { const driver = this.browser.getDriver(); try { const locator = By.css(selector); await this._waitForElement(driver, locator); const element = await driver.findElement(locator); // make sure we clear it await element.clear(); return element.sendKeys(text); } catch (error) { const url = await this._getUrl(); log.error( 'Could not add text %s to selector %s error: %s', text, selector, error.message ); log.verbose(error); throw new Error( `Could not add text ${text} to selector ${selector}${url}` ); } } /** * Adds text to an element identified by its class name. * * @async * @private * @example commands.addText.byClassName('mytext', 'className'); * @param {string} text - The text string to add. * @param {string} className - The class name of the element. * @returns {Promise<void>} A promise that resolves when the text has been added. * @throws {Error} Throws an error if the element is not found. */ async byClassName(text, className) { const driver = this.browser.getDriver(); try { const locator = By.className(className); await this._waitForElement(driver, locator); const element = await driver.findElement(locator); // make sure we clear it await element.clear(); return element.sendKeys(text); } catch (error) { const url = await this._getUrl(); log.error( 'Could not add text %s to class name %s error: %s', text, className, error.message ); log.verbose(error); throw new Error( `Could not add text ${text} to class name ${className}${url}` ); } } /** * Adds text to an element identified by its name attribute. * * @async * @private * @example commands.addText.byName('mytext', 'name'); * @param {string} text - The text string to add. * @param {string} name - The name attribute of the element. * @returns {Promise<void>} A promise that resolves when the text has been added. * @throws {Error} Throws an error if the element is not found. */ async byName(text, name) { const driver = this.browser.getDriver(); try { const locator = By.name(name); await this._waitForElement(driver, locator); const element = await driver.findElement(locator); // make sure we clear it await element.clear(); return element.sendKeys(text); } catch (error) { const url = await this._getUrl(); log.error( 'Could not add text %s to name attribute %s error: %s', text, name, error.message ); log.verbose(error); throw new Error( `Could not add text ${text} to name attribute ${name}${url}` ); } } }