Description
What are you trying to achieve?
I've been trying to use within in some of my test cases and noticed that its behavior isn't consistent across different assertions. I'm testing this by using an element that is present on page but should fail inside the context given to within. Tested on both Puppeteer or Playwright.
What do you get instead?
I'm trying to verify that an element is not present inside the given context. dontSeeElement
correctly succeeds as it only searches inside the given context but waitForInvisible
fails because it always uses the full page as a context.
I've looked through the source code to try and debug this and it seems like the issue is in _getContext
method.
waitFor*
assertions (at least those that I've looked at) determine the searchable context by calling _getContext which only returns this.context
if it points to a FrameLocator
(Playwright) or CdpFrame
(Puppeteer), otherwise it defaults to the whole page.
(dont)see*
assertions on the other hand use _locate
which uses this.context
that gets set inside _withinBegin
.
I am aware that documentation suggests refactoring without using within in case of unexpected results but given those snippets I would expect it to work on regular locators too, not just limited to frames. At the very least if within is expected to only work with frames I think this should be noted in the docs. What's the proper behavior?
Provide console output if related. Use
--verbose
mode for more details.
within --
testing within
I am on page "https://codecept.io/"
I wait for visible ".frameworks"
I wait for visible "[alt="React"]"
I wait for visible ".mountains"
Within ".mountains" ""
I dont see element "[alt="React"]"
I wait for invisible "[alt="React"]", 2
✖ FAILED in 3896ms
-- FAILURES:
1) within
testing within:
Error: element ([alt="React"]) still visible after 2 sec
Waiting for selector `[alt="React"]` failed: Waiting failed: 2000ms exceeded
Provide test source code if related
Feature('within');
Scenario('testing within', ({ I }) => {
I.amOnPage('https://codecept.io/')
I.waitForVisible('.frameworks')
I.waitForVisible('[alt="React"]')
I.waitForVisible('.mountains')
within('.mountains', () => {
I.dontSeeElement('[alt="React"]')
I.waitForInvisible('[alt="React"]', 2)
})
});
Details
- CodeceptJS version: 3.6.7
- NodeJS Version: v20.10.0
- Operating System: macOS Sonoma 14.7
- puppeteer || webdriverio || testcafe version (if related): Puppeteer 21.11.0 and Playwright 1.48.2
- Configuration file: (default config that's generated by
codeceptjs init
command)
const { setHeadlessWhen, setCommonPlugins } = require('@codeceptjs/configure');
// turn on headless mode when running with HEADLESS=true environment variable
// export HEADLESS=true && npx codeceptjs run
setHeadlessWhen(process.env.HEADLESS);
// enable all common plugins https://github.com/codeceptjs/configure#setcommonplugins
setCommonPlugins();
/** @type {CodeceptJS.MainConfig} */
exports.config = {
tests: './*_test.js',
output: './output',
helpers: {
Playwright: {
browser: 'chromium',
url: 'https://codecept.io',
show: true,
waitForTimeout: 10000,
}
},
include: {
I: './steps_file.js'
},
name: 'withintest'
}