<p dir="auto"><strong>Let us know what functionality you'd like to see in Playwright and what is your use case.</strong><br>
A special locator to visually locate an element.</p>
<p dir="auto">In taiko, browser automation library by thoughtwork, you could locate element visually like the following:<br>
<code class="notranslate">click(checkbox(near("Username")))</code></p>
<p dir="auto">Taiko calls it proximity locator<br>
Refer: <a href="https://docs.taiko.dev/#smart-selectors" rel="nofollow">https://docs.taiko.dev/#smart-selectors</a></p>
<p dir="auto">This locator will reduce the flakiness of the script and the maintenance cost because the locator doesn't rely on html structure that may be changed from time to time. Even we can assign data-testid attribute but this is very useful in some cases as well.</p>
<p dir="auto"><strong>Do you think others might benefit from this as well?</strong><br>
Yes, it is.</p>
<h3 dir="auto">System info</h3>
<ul dir="auto">
<li>Playwright Version: v1.32.3</li>
<li>Operating System: macOS 13.3.1</li>
<li>Browser: All</li>
<li>Other info: pnpm v7 as package manager on Node v16</li>
</ul>
<h3 dir="auto">Source code</h3>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I provided exact source code that allows reproducing the issue locally.</li>
</ul>




<p dir="auto"><strong>Link to the GitHub repository with the repro</strong></p>
<p dir="auto"><a href="https://github.com/segevfiner/playwright-core-version-conflict">https://github.com/segevfiner/playwright-core-version-conflict</a></p>
<p dir="auto"><strong>Steps</strong></p>
<ul dir="auto">
<li>Run <code class="notranslate">pnpm install</code></li>
<li>Try running <code class="notranslate">pnpm playwright test</code> in the <code class="notranslate">apps/a</code> and <code class="notranslate">apps/b</code> directories.</li>
<li>On of them will fail with an error message of this sort:</li>
</ul>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="╔═════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
║ Playwright Test integrity check failed:                                                                     ║
║ You have @playwright/test version '1.32.3' and 'playwright-core' version '1.32.2' installed!                ║
║ You probably added 'playwright-core' into your package.json by accident, remove it and re-run 'npm install' ║
╚═════════════════════════════════════════════════════════════════════════════════════════════════════════════╝"><pre class="notranslate"><code class="notranslate">╔═════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
║ Playwright Test integrity check failed:                                                                     ║
║ You have @playwright/test version '1.32.3' and 'playwright-core' version '1.32.2' installed!                ║
║ You probably added 'playwright-core' into your package.json by accident, remove it and re-run 'npm install' ║
╚═════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
</code></pre></div>
<p dir="auto"><strong>Expected</strong></p>
<p dir="auto">For the tests of both packages the work.</p>
<p dir="auto"><strong>Actual</strong></p>
<p dir="auto">A Playwright test integrity check failed error.</p>
<h3 dir="auto">Analysis</h3>
<p dir="auto">This is caused by the way pnpm hoists dependencies. Since <code class="notranslate">playwright-core</code> doesn't declare that <code class="notranslate">@playwright/test</code> as a peer dependency, pnpm isn't going to create separate trees for it in the virtual store with the actual <code class="notranslate">@playwright/test</code> version that is required by each package, rather there will only be one <code class="notranslate">playwright-core</code> used by both, which then when importing <code class="notranslate">@playwright/test</code> will get an arbitrary version of <code class="notranslate">@playwright/test</code> that happens to be the one that was hoisted.</p>
<p dir="auto">I suggested a fix here <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="1681172527" data-permission-text="Title is private" data-url="https://github.com/microsoft/playwright/issues/22595" data-hovercard-type="pull_request" data-hovercard-url="/microsoft/playwright/pull/22595/hovercard" href="https://github.com/microsoft/playwright/pull/22595">#22595</a>, but it was rejected by <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/pavelfeldman/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/pavelfeldman">@pavelfeldman</a>, which requested I open an issue instead.</p>
<p dir="auto">Note that the behavior with dependencies, peer dependencies, and CLI's (AKA <code class="notranslate">bin</code>) is very subtle, as it stands both <code class="notranslate">playwright-core</code> and <code class="notranslate">@playwright/test</code> declare the <code class="notranslate">bin</code>, which means one of them wins arbitrary and will be what gets invoked by the package manager. Also note that <code class="notranslate">@playwright/experimental-ct-vue</code> and the like also do the same. So just moving the CLI to one of those packages might not be as trivial as they will fight each other.</p>