Skip to content

Commit

Permalink
feat(playwright): wait for disabled (#4412)
Browse files Browse the repository at this point in the history
  • Loading branch information
kobenguyent authored Jul 23, 2024
1 parent 7769c02 commit 03943c1
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 5 deletions.
12 changes: 12 additions & 0 deletions docs/helpers/Playwright.md
Original file line number Diff line number Diff line change
Expand Up @@ -2444,6 +2444,18 @@ I.waitForDetached('#popup');

Returns **void** automatically synchronized promise through #recorder

### waitForDisabled

Waits for element to become disabled (by default waits for 1sec).
Element can be located by CSS or XPath.

#### Parameters

- `locator` **([string][9] | [object][6])** element located by CSS|XPath|strict locator.
- `sec` **[number][20]** (optional) time in seconds to wait, 1 by default.

Returns **void** automatically synchronized promise through #recorder

### waitForElement

Waits for element to be present on page (by default waits for 1sec).
Expand Down
6 changes: 6 additions & 0 deletions docs/webapi/waitForDisabled.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Waits for element to become disabled (by default waits for 1sec).
Element can be located by CSS or XPath.

@param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
@param {number} [sec=1] (optional) time in seconds to wait, 1 by default.
@returns {void} automatically synchronized promise through #recorder
30 changes: 29 additions & 1 deletion lib/helper/Playwright.js
Original file line number Diff line number Diff line change
Expand Up @@ -2476,7 +2476,7 @@ class Playwright extends Helper {
async waitForEnabled(locator, sec) {
const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout
locator = new Locator(locator, 'css')
const matcher = await this.context

let waiter
const context = await this._getContext()
if (!locator.isXPath()) {
Expand All @@ -2498,6 +2498,34 @@ class Playwright extends Helper {
})
}

/**
* {{> waitForDisabled }}
*/
async waitForDisabled(locator, sec) {
const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout
locator = new Locator(locator, 'css')

let waiter
const context = await this._getContext()
if (!locator.isXPath()) {
const valueFn = function ([locator]) {
return Array.from(document.querySelectorAll(locator)).filter((el) => el.disabled).length > 0
}
waiter = context.waitForFunction(valueFn, [locator.value], { timeout: waitTimeout })
} else {
const disabledFn = function ([locator, $XPath]) {
eval($XPath) // eslint-disable-line no-eval
return $XPath(null, locator).filter((el) => el.disabled).length > 0
}
waiter = context.waitForFunction(disabledFn, [locator.value, $XPath.toString()], { timeout: waitTimeout })
}
return waiter.catch((err) => {
throw new Error(
`element (${locator.toString()}) is still enabled after ${waitTimeout / 1000} sec\n${err.message}`,
)
})
}

/**
* {{> waitForValue }}
*/
Expand Down
12 changes: 8 additions & 4 deletions lib/helper/REST.js
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ class REST extends Helper {
: this.debugSection('Request', JSON.stringify(_debugRequest))

if (this.options.printCurl) {
this.debugSection('CURL Request', curlize(request));
this.debugSection('CURL Request', curlize(request))
}

let response
Expand Down Expand Up @@ -393,8 +393,13 @@ class REST extends Helper {
module.exports = REST

function curlize(request) {
if (request.data?.constructor.name.toLowerCase() === 'formdata') return 'cURL is not printed as the request body is not a JSON'
let curl = `curl --location --request ${request.method ? request.method.toUpperCase() : 'GET'} ${request.baseURL} `.replace("'", '')
if (request.data?.constructor.name.toLowerCase() === 'formdata')
return 'cURL is not printed as the request body is not a JSON'
let curl =
`curl --location --request ${request.method ? request.method.toUpperCase() : 'GET'} ${request.baseURL} `.replace(
"'",
'',
)

if (request.headers) {
Object.entries(request.headers).forEach(([key, value]) => {
Expand All @@ -411,4 +416,3 @@ function curlize(request) {
}
return curl
}

21 changes: 21 additions & 0 deletions test/data/app/view/form/wait_disabled.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<html>
<body>

<input id="text" type="text" name="test" disabled="true" value="some text">

<button id="button" type="button" name="button1" disabled="true" value="first" onclick="updateMessage('button was clicked')">A Button</button>

<div id="message"></div>

<script>
setTimeout(function () {
document.querySelector('#text').disabled = false;
document.querySelector('#button').disabled = false;
}, 2000);
function updateMessage(msg) {
document.querySelector('#message').textContent = msg;
}
</script>
</body>
</html>
11 changes: 11 additions & 0 deletions test/helper/Playwright_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,17 @@ describe('Playwright', function () {
.then(() => I.see('button was clicked', '#message')))
})

describe('#waitForDisabled', () => {
it('should wait for input text field to be disabled', () =>
I.amOnPage('/form/wait_disabled').then(() => I.waitForDisabled('#text', 1)))

it('should wait for input text field to be enabled by xpath', () =>
I.amOnPage('/form/wait_disabled').then(() => I.waitForDisabled("//*[@name = 'test']", 1)))

it('should wait for a button to be disabled', () =>
I.amOnPage('/form/wait_disabled').then(() => I.waitForDisabled('#text', 1)))
})

describe('#waitForValue', () => {
it('should wait for expected value for given locator', () =>
I.amOnPage('/info')
Expand Down

0 comments on commit 03943c1

Please sign in to comment.