codeceptjs / CodeceptJS

Supercharged End 2 End Testing Framework for NodeJS

Home Page:http://codecept.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Locator builder produces incorrect value for "locate().withText().inside()"

mirao opened this issue Β· comments

What are you trying to achieve?

locate(".ps-menu-button").withText("Authoring").inside(".ps-submenu-root:nth-child(3)") is translated to XPath that matches an element on page

  • 3.5.8: //*[contains(concat(' ', normalize-space(./@class), ' '), ' ps-menu-button ')][contains(., 'Authoring')][ancestor::*[(contains(concat(' ', normalize-space(./@class), ' '), ' ps-submenu-root ') and count(preceding-sibling::*) = 2)]] works βœ”οΈ

image
image

What do you get instead?

  • 3.5.10/3.5.11: //*[contains(@class, "ps-menu-button")][contains(., 'Authoring')][ancestor::*[3][contains(@class, "ps-submenu-root")]] doesn't work (neither in test nor in web browser inspector) 🐞
  • 3.5.12: //*[@class and contains(concat(' ', normalize-space(@class), ' '), ' ps-menu-button ')][contains(., 'Authoring')][ancestor::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' ps-submenu-root ') and (position() = 3)]] doesn't work (neither in test nor in web browser inspector) 🐞
    • The fix #4101 didn't help

Details

  • CodeceptJS version: 3.5.12
  • NodeJS Version: v18.15.0
  • Operating System: Ubuntu 22.04

Steps to reproduce:

  • Open an empty HTML page in Chrome
  • Dev Tools => Elements
  • Edit "body" as HTML
  • Copy and paste the following HTML under a body
<ul class="css-ewdv3l">
    <li class="ps-menuitem-root css-dq4uaz">
        <a
            aria-current="page"
            class="ps-menu-button active"
            data-testid="ps-menu-button-test-id"
            tabindex="0"
            title="aaa"
            href="/"
            ><span class="ps-menu-icon css-2wa2k3"
                ><i aria-hidden="true" class="icon home lg outline"></i></span
            ><span class="ps-menu-label css-12w9als">aaa</span></a
        >
    </li>
    <li class="ps-menuitem-root ps-submenu-root css-x7nyah">
        <a
            class="ps-menu-button"
            data-testid="ps-menu-button-test-id"
            title="Dashboard"
            tabindex="0"
            ><span class="ps-menu-icon css-2wa2k3"
                ><i
                    aria-hidden="true"
                    class="icon tachometer alternate"
                ></i></span
            ><span class="ps-menu-label css-12w9als">aaa</span
            ><span class="ps-submenu-expand-icon css-1cuxlhl"
                ><span class="css-honxw6"></span></span
        ></a>
    </li>
    <li class="ps-menuitem-root ps-submenu-root css-x7nyah">
        <a
            class="ps-menu-button"
            data-testid="ps-menu-button-test-id"
            title="aaa"
            tabindex="0"
            ><span class="ps-menu-icon css-2wa2k3"
                ><i aria-hidden="true" class="icon books"></i></span
            ><span class="ps-menu-label css-12w9als">Authoring</span
            ><span class="ps-submenu-expand-icon css-1cuxlhl"
                ><span class="css-honxw6"></span></span
        ></a>
    </li>
    <li class="ps-menuitem-root ps-submenu-root css-x7nyah">
        <a
            class="ps-menu-button"
            data-testid="ps-menu-button-test-id"
            title="aaa"
            tabindex="0"
            ><span class="ps-menu-icon css-2wa2k3"
                ><i aria-hidden="true" class="icon ballot check"></i></span
            ><span class="ps-menu-label css-12w9als">aaa</span
            ><span class="ps-submenu-expand-icon css-1cuxlhl"
                ><span class="css-honxw6"></span></span
        ></a>
    </li>
    <li class="ps-menuitem-root ps-submenu-root css-x7nyah">
        <a
            class="ps-menu-button"
            data-testid="ps-menu-button-test-id"
            title="aaa"
            tabindex="0"
            ><span class="ps-menu-icon css-2wa2k3"
                ><i aria-hidden="true" class="icon book reader"></i></span
            ><span class="ps-menu-label css-12w9als">aaa</span
            ><span class="ps-submenu-expand-icon css-1cuxlhl"
                ><span class="css-honxw6"></span></span
        ></a>
    </li>
    <li class="ps-menuitem-root ps-submenu-root css-x7nyah">
        <a
            class="ps-menu-button"
            data-testid="ps-menu-button-test-id"
            title="aaa"
            tabindex="0"
            ><span class="ps-menu-icon css-2wa2k3"
                ><i aria-hidden="true" class="icon school"></i></span
            ><span class="ps-menu-label css-12w9als">aaa</span
            ><span class="ps-submenu-expand-icon css-1cuxlhl"
                ><span class="css-honxw6"></span></span
        ></a>
    </li>
    <li class="ps-menuitem-root ps-submenu-root css-x7nyah">
        <a
            class="ps-menu-button"
            data-testid="ps-menu-button-test-id"
            title="aaa"
            tabindex="0"
            ><span class="ps-menu-icon css-2wa2k3"
                ><i aria-hidden="true" class="icon user"></i></span
            ><span class="ps-menu-label css-12w9als">aaa</span
            ><span class="ps-submenu-expand-icon css-1cuxlhl"
                ><span class="css-honxw6"></span></span
        ></a>
    </li>
    <li class="ps-menuitem-root ps-submenu-root css-x7nyah">
        <a
            class="ps-menu-button"
            data-testid="ps-menu-button-test-id"
            title="aaa"
            tabindex="0"
            ><span class="ps-menu-icon css-2wa2k3"
                ><i aria-hidden="true" class="icon cog"></i></span
            ><span class="ps-menu-label css-12w9als">aaa</span
            ><span class="ps-submenu-expand-icon css-1cuxlhl"
                ><span class="css-honxw6"></span></span
        ></a>
    </li>
    <li class="ps-menuitem-root ps-submenu-root css-x7nyah">
        <a
            class="ps-menu-button"
            data-testid="ps-menu-button-test-id"
            title="aaa"
            tabindex="0"
            ><span class="ps-menu-icon css-2wa2k3"
                ><i aria-hidden="true" class="icon tablet alternate"></i></span
            ><span class="ps-menu-label css-12w9als">aaa</span
            ><span class="ps-submenu-expand-icon css-1cuxlhl"
                ><span class="css-honxw6"></span></span
        ></a>
    </li>
    <li class="ps-menuitem-root ps-submenu-root css-x7nyah">
        <a
            class="ps-menu-button"
            data-testid="ps-menu-button-test-id"
            title="aaa"
            tabindex="0"
            ><span class="ps-menu-icon css-2wa2k3"
                ><i aria-hidden="true" class="icon tools"></i></span
            ><span class="ps-menu-label css-12w9als">aaa</span
            ><span class="ps-submenu-expand-icon css-1cuxlhl"
                ><span class="css-honxw6"></span></span
        ></a>
    </li>
</ul>

If you use the XPath locator translated in CodeceptJS 3.5.8 (see my original report), the element is found βœ”οΈ
image

If you use the XPath locator translated in CodeceptJS 3.5.12, the element is not found 🐞

that's strange, we have added this test there https://github.com/codeceptjs/CodeceptJS/blob/3.x/test/unit/locator_test.js#L296

may you help check if the test is not proper?

@kobenguyent The scenario in the test passes (and the result works in web inspector), but I guess because the test HTML data is "too simple".

A workaround for our test case:

  • if we use (A): locate(".ps-submenu-root:nth-child(3)").find(".ps-menu-button").withText("Authoring")
  • instead of (B): locate(".ps-menu-button").withText("Authoring").inside(".ps-submenu-root:nth-child(3)")

then the element matches as expected

  • (A) is translated to //*[@class and contains(concat(' ', normalize-space(@class), ' '), ' ps-submenu-root ') and (position() = 3)]//*[@class and contains(concat(' ', normalize-space(@class), ' '), ' ps-menu-button ')][contains(., 'Authoring')], it works βœ”οΈ
  • (B) is translated to //*[@class and contains(concat(' ', normalize-space(@class), ' '), ' ps-menu-button ')][contains(., 'Authoring')][ancestor::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' ps-submenu-root ') and (position() = 3)]], it doesn't work 🐞

It seems that adding of ':nth-child' into the array

const limitation = [':nth-of-type', ':first-of-type', ':last-of-type', ':nth-last-child', ':nth-last-of-type', ':checked', ':disabled', ':enabled', ':required', ':lang'];

fixes our issue. Then an old conversion way over css-to-xpath is used.