-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
How to use Codeception with web components using shadow? #6824
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Hi, I found a way to make this work for me. It's really not ideal, but a good enough solution for now. I added a method which allows css-selectors with a <?php
declare(strict_types=1);
namespace Tests\Support\Helper;
use Codeception\Module\WebDriver;
use Facebook\WebDriver\Remote\RemoteWebElement;
use Facebook\WebDriver\WebDriverBy;
class ShadowAwareWebDriver extends WebDriver
{
public function findElement(string $selector): RemoteWebElement
{
$items = $this->findElements($selector);
return $items[array_key_first($items)];
}
/**
* @param string $selector
* @return RemoteWebElement[]
*/
public function findElements(string $selector): array
{
if (!str_contains($selector, '::shadow')) {
return $this->_findElements($selector);
}
$selectors = array_map(
fn(string $selector) => WebDriverBy::cssSelector(trim($selector)),
explode('::shadow', $selector)
);
$firstSelector = array_shift($selectors);
$topLevelRoots = $this->_findElements($firstSelector);
$result = [];
foreach ($topLevelRoots as $root) {
foreach ($this->resolveShadowSelector($root, $selectors) as $element) {
$result[] = $element;
}
}
return $result;
}
/**
* @param WebDriverBy[] $selectors
* @return RemoteWebElement[]
*/
protected function resolveShadowSelector(RemoteWebElement $root, array $selectors): array
{
if (empty($selectors)) {
return [];
}
$selector = array_shift($selectors);
$subs = $root->getShadowRoot()->findElements($selector);
if (empty($selectors)) {
return $subs;
}
$result = [];
foreach($subs as $sub) {
foreach ($this->resolveShadowSelector($sub, $selectors) as $fromSub) {
$result[] = $fromSub;
}
}
return $result;
}
} And I registered that one in the config: suites:
acceptance:
actor: AcceptanceTester
path: .
modules:
enabled:
- \Tests\Support\Helper\ShadowAwareWebDriver: In my tests I can now use that method: $shadowDom = $this->findElement('parent-web-component::shadow child-web-component')->getShadowRoot();
$shadowDom->findElement(WebDriverBy::cssSelector('#my-selector')); With this I am now able to access the shadow dom / shadow root. One more thing: Is there any reason, why |
Hi,
we are using web components with shadow DOM. Is it possible to access the shadow DOM with built-in functions of Codeception?
How to reproduce?
I didn't find a way to access the div in a shadow root.
The only way I would see is, to execute js with
$I->executeJS();
but relying on this function for testing a complete application seems horrible to me.Any ideas or tips?
Best Regards
mschop
The text was updated successfully, but these errors were encountered: