Skip to content

Different behavior of see* and waitFor* when used in within #4547

Closed
@nikzupancic

Description

@nikzupancic

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'
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions