Skip to content
Merged
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: 33 additions & 28 deletions lib/helper/Playwright.js
Original file line number Diff line number Diff line change
Expand Up @@ -2687,6 +2687,9 @@ class Playwright extends Helper {
if ((this.context && this.context.constructor.name === 'FrameLocator') || this.context) {
return this.context
}
if (this.frame) {
return this.frame
}
return this.page
}

Expand Down Expand Up @@ -2751,26 +2754,21 @@ class Playwright extends Helper {
async waitForText(text, sec = null, context = null) {
const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout
const errorMessage = `Text "${text}" was not found on page after ${waitTimeout / 1000} sec.`
let waiter

const contextObject = await this._getContext()

if (context) {
const locator = new Locator(context, 'css')
if (!locator.isXPath()) {
try {
await contextObject
try {
if (!locator.isXPath()) {
return contextObject
.locator(`${locator.isCustom() ? `${locator.type}=${locator.value}` : locator.simplify()} >> text=${text}`)
.first()
.waitFor({ timeout: waitTimeout, state: 'visible' })
} catch (e) {
throw new Error(`${errorMessage}\n${e.message}`)
}
}

if (locator.isXPath()) {
try {
await contextObject.waitForFunction(
if (locator.isXPath()) {
return contextObject.waitForFunction(
([locator, text, $XPath]) => {
eval($XPath) // eslint-disable-line no-eval
const el = $XPath(null, locator)
Expand All @@ -2780,27 +2778,34 @@ class Playwright extends Helper {
[locator.value, text, $XPath.toString()],
{ timeout: waitTimeout },
)
} catch (e) {
throw new Error(`${errorMessage}\n${e.message}`)
}
} catch (e) {
throw new Error(`${errorMessage}\n${e.message}`)
}
} else {
// we have this as https://github.com/microsoft/playwright/issues/26829 is not yet implemented

const _contextObject = this.frame ? this.frame : contextObject
let count = 0
do {
waiter = await _contextObject
.locator(`:has-text(${JSON.stringify(text)})`)
.first()
.isVisible()
if (waiter) break
await this.wait(1)
count += 1000
} while (count <= waitTimeout)

if (!waiter) throw new Error(`${errorMessage}`)
}

const timeoutGap = waitTimeout + 1000

// We add basic timeout to make sure we don't wait forever
// We apply 2 strategies here: wait for text as innert text on page (wide strategy) - older
// or we use native Playwright matcher to wait for text in element (narrow strategy) - newer
// If a user waits for text on a page they are mostly expect it to be there, so wide strategy can be helpful even PW strategy is available
return Promise.race([
new Promise((_, reject) => {
setTimeout(() => reject(errorMessage), waitTimeout)
}),
this.page.waitForFunction(text => document.body && document.body.innerText.indexOf(text) > -1, text, { timeout: timeoutGap }),
promiseRetry(
async retry => {
const textPresent = await contextObject
.locator(`:has-text(${JSON.stringify(text)})`)
.first()
.isVisible()
if (!textPresent) retry(errorMessage)
},
{ retries: 1000, minTimeout: 500, maxTimeout: 500, factor: 1 },
),
])
}

/**
Expand Down
Loading