Open tejas-elsner opened 2 years ago
I guess that you want it in WebDriver module.
You are welcome to implement this feature and raise pull request.
The underlying library added support: https://github.com/php-webdriver/php-webdriver/pull/1010 So someone with the necessary knowledge should be able to add this to the module. I need this right now and will play around with this. I'll share my insights if they are helpful.
It looks like Firefox added ShadowDom support as well, but still lacks support for some locators, see: https://github.com/w3c/webdriver/issues/1610 so adding support within the module might end in requests why things aren't working which is an underlying issue.
I came up with the following:
diff --git a/src/Codeception/Module/WebDriver.php b/src/Codeception/Module/WebDriver.php
index 2c5b578..51492f1 100644
--- a/src/Codeception/Module/WebDriver.php
+++ b/src/Codeception/Module/WebDriver.php
@@ -1176,9 +1176,9 @@ class WebDriver extends CodeceptionModule implements
public function click($link, $context = null): void
{
- $page = $this->webDriver;
+ $page = $this->getBaseElement();
if ($context) {
- $page = $this->matchFirstOrFail($this->webDriver, $context);
+ $page = $this->matchFirstOrFail($page, $context);
}
$el = $this->_findClickable($page, $link);
@@ -3661,6 +3661,32 @@ class WebDriver extends CodeceptionModule implements
$this->setBaseElement();
}
+ public function performOnShadowRoot($element, $actions, int $timeout = 10): void
+ {
+ $this->waitForElement($element, $timeout);
+ $this->setBaseElement($element);
+ $this->debugSection('InnerText', $this->getBaseElement()->getText());
+
+ $this->baseElement = $this->getBaseElement()->getShadowRoot();
+
+ if (is_callable($actions)) {
+ $actions($this);
+ $this->setBaseElement();
+ return;
+ }
+
+ if (is_array($actions)) {
+ $actions = ActionSequence::build()->fromArray($actions);
+ }
+
+ if (!$actions instanceof ActionSequence) {
+ throw new InvalidArgumentException("2nd parameter, actions should be callback, ActionSequence or array");
+ }
+
+ $actions->run($this);
+ $this->setBaseElement();
+ }
+
/**
* @param string|array|WebDriverBy $element
*/
That way it could be used like this:
$this->tester->performOnShadowRoot(
'typo3-backend-new-content-element-wizard',
ActionSequence::build()
->click("//span[normalize-space(.)='$tabName']")
->click("//span[normalize-space(.)='$contentElementLabel']")
);
Following the existing performOn()
approach.
I had to fix the click()
method that does not seem to respect the base Element in current version.
I also noticed that the performOn won't work with additions like step decorators, e.g. Codeception\Step\Retry
.
Also ShadowDom via WebDriver in Browsers currently doesn't seem to support various locators, e..g XPath. So our above example won't work.
Due to all those issues I didn't open a PR. I don't have the feeling general shadow dom support is there yet … But feel free to use the patch and provide a PR or patch your own code.
What are you trying to achieve?
Get the Shadow Dom
What do you get instead?
Not able to get the result from Shadow root
Details
composer show
)