Skip to content
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
93 changes: 37 additions & 56 deletions lib/helper/Playwright.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import ElementNotFound from './errors/ElementNotFound.js'
import RemoteBrowserConnectionRefused from './errors/RemoteBrowserConnectionRefused.js'
import Popup from './extras/Popup.js'
import Console from './extras/Console.js'
import { findReact, findVue, findByPlaywrightLocator } from './extras/PlaywrightReactVueLocator.js'
import { buildLocatorString, findElements, findElement, getVisibleElements, findReact, findVue, findByPlaywrightLocator, findByRole } from './extras/PlaywrightLocator.js'

let playwright
let perfTiming
Expand Down Expand Up @@ -2424,17 +2424,28 @@ class Playwright extends Helper {
*
*/
async grabTextFrom(locator) {
locator = this._contextLocator(locator)
const originalLocator = locator
const matchedLocator = new Locator(locator)

if (!matchedLocator.isFuzzy()) {
const els = await this._locate(matchedLocator)
assertElementExists(els, locator)
const text = await els[0].innerText()
this.debugSection('Text', text)
return text
}

const contextAwareLocator = this._contextLocator(matchedLocator.value)
let text
try {
text = await this.page.textContent(locator)
text = await this.page.textContent(contextAwareLocator)
} catch (err) {
if (err.message.includes('Timeout') || err.message.includes('exceeded')) {
throw new Error(`Element ${new Locator(locator).toString()} was not found by text|CSS|XPath`)
throw new Error(`Element ${new Locator(originalLocator).toString()} was not found by text|CSS|XPath`)
}
throw err
}
assertElementExists(text, locator)
assertElementExists(text, contextAwareLocator)
this.debugSection('Text', text)
return text
}
Expand Down Expand Up @@ -3821,47 +3832,6 @@ class Playwright extends Helper {

export default Playwright

function buildLocatorString(locator) {
if (locator.isCustom()) {
return `${locator.type}=${locator.value}`
}
if (locator.isXPath()) {
return `xpath=${locator.value}`
}
return locator.simplify()
}

async function findElements(matcher, locator) {
if (locator.react) return findReact(matcher, locator)
if (locator.vue) return findVue(matcher, locator)
if (locator.pw) return findByPlaywrightLocator.call(this, matcher, locator)
locator = new Locator(locator, 'css')

return matcher.locator(buildLocatorString(locator)).all()
}

async function findElement(matcher, locator) {
if (locator.react) return findReact(matcher, locator)
if (locator.vue) return findVue(matcher, locator)
if (locator.pw) return findByPlaywrightLocator.call(this, matcher, locator)
locator = new Locator(locator, 'css')

return matcher.locator(buildLocatorString(locator)).first()
}

async function getVisibleElements(elements) {
const visibleElements = []
for (const element of elements) {
if (await element.isVisible()) {
visibleElements.push(element)
}
}
if (visibleElements.length === 0) {
return elements
}
return visibleElements
}

async function proceedClick(locator, context = null, options = {}) {
let matcher = await this._getContext()
if (context) {
Expand Down Expand Up @@ -3898,15 +3868,26 @@ async function proceedClick(locator, context = null, options = {}) {
}

async function findClickable(matcher, locator) {
if (locator.react) return findReact(matcher, locator)
if (locator.vue) return findVue(matcher, locator)
if (locator.pw) return findByPlaywrightLocator.call(this, matcher, locator)
const matchedLocator = new Locator(locator)

locator = new Locator(locator)
if (!locator.isFuzzy()) return findElements.call(this, matcher, locator)
if (!matchedLocator.isFuzzy()) return findElements.call(this, matcher, matchedLocator)

let els
const literal = xpathLocator.literal(locator.value)
const literal = xpathLocator.literal(matchedLocator.value)

try {
els = await matcher.getByRole('button', { name: matchedLocator.value }).all()
if (els.length) return els
} catch (err) {
// getByRole not supported or failed
}

try {
els = await matcher.getByRole('link', { name: matchedLocator.value }).all()
if (els.length) return els
} catch (err) {
// getByRole not supported or failed
}

els = await findElements.call(this, matcher, Locator.clickable.narrow(literal))
if (els.length) return els
Expand All @@ -3921,7 +3902,7 @@ async function findClickable(matcher, locator) {
// Do nothing
}

return findElements.call(this, matcher, locator.value) // by css or xpath
return findElements.call(this, matcher, matchedLocator.value) // by css or xpath
}

async function proceedSee(assertType, text, context, strict = false) {
Expand Down Expand Up @@ -3962,10 +3943,10 @@ async function findCheckable(locator, context) {

const matchedLocator = new Locator(locator)
if (!matchedLocator.isFuzzy()) {
return findElements.call(this, contextEl, matchedLocator.simplify())
return findElements.call(this, contextEl, matchedLocator)
}

const literal = xpathLocator.literal(locator)
const literal = xpathLocator.literal(matchedLocator.value)
let els = await findElements.call(this, contextEl, Locator.checkable.byText(literal))
if (els.length) {
return els
Expand All @@ -3974,7 +3955,7 @@ async function findCheckable(locator, context) {
if (els.length) {
return els
}
return findElements.call(this, contextEl, locator)
return findElements.call(this, contextEl, matchedLocator.value)
}

async function proceedIsChecked(assertType, option) {
Expand Down
Loading
Loading