-
-
Notifications
You must be signed in to change notification settings - Fork 8.5k
[java] Fix: Convert By.className to css selector for Firefox inside Shadow DOM #16085
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
base: trunk
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,6 +31,7 @@ | |
import org.openqa.selenium.WebElement; | ||
import org.openqa.selenium.WrapsDriver; | ||
import org.openqa.selenium.internal.Require; | ||
import org.openqa.selenium.remote.shadow.FirefoxClassNameWorkaround; | ||
|
||
// Note: we want people to code against the SearchContext API, so we keep this class package private | ||
class ShadowRoot implements SearchContext, WrapsDriver { | ||
|
@@ -44,18 +45,20 @@ class ShadowRoot implements SearchContext, WrapsDriver { | |
|
||
@Override | ||
public List<WebElement> findElements(By by) { | ||
By resolved = FirefoxClassNameWorkaround.resolveForShadow(by, this); | ||
return parent.findElements( | ||
this, | ||
(using, value) -> FIND_ELEMENTS_FROM_SHADOW_ROOT(id, using, String.valueOf(value)), | ||
by); | ||
resolved); | ||
} | ||
|
||
@Override | ||
public WebElement findElement(By by) { | ||
By resolved = FirefoxClassNameWorkaround.resolveForShadow(by, this); | ||
return parent.findElement( | ||
this, | ||
(using, value) -> FIND_ELEMENT_FROM_SHADOW_ROOT(id, using, String.valueOf(value)), | ||
by); | ||
resolved); | ||
} | ||
|
||
@Override | ||
|
@@ -73,12 +76,8 @@ private Map<String, Object> toJson() { | |
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (o == null || getClass() != o.getClass()) { | ||
return false; | ||
} | ||
if (this == o) return true; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please avoid formatting changes as part of a PR. If required, create a separate PR for it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you for the review @pujagani 🙏
Thanks again for the guidance. Will push the updates soon. |
||
if (o == null || getClass() != o.getClass()) return false; | ||
ShadowRoot that = (ShadowRoot) o; | ||
return Objects.equals(parent, that.parent) && Objects.equals(id, that.id); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package org.openqa.selenium.remote.shadow; | ||
|
||
import org.openqa.selenium.By; | ||
import org.openqa.selenium.InvalidSelectorException; | ||
import org.openqa.selenium.SearchContext; | ||
import org.openqa.selenium.WebDriver; | ||
import org.openqa.selenium.WrapsDriver; | ||
import org.openqa.selenium.remote.HasCapabilities; | ||
import org.openqa.selenium.Capabilities; | ||
|
||
final class FirefoxClassNameWorkaround { | ||
|
||
static boolean shouldUseCssSelector(By by, SearchContext context) { | ||
if (!(by instanceof By.ByClassName)) return false; | ||
if (!(context instanceof WrapsDriver)) return false; | ||
|
||
try { | ||
WebDriver driver = ((WrapsDriver) context).getWrappedDriver(); | ||
Capabilities caps = ((HasCapabilities) driver).getCapabilities(); | ||
return "firefox".equalsIgnoreCase(caps.getBrowserName()); | ||
} catch (Exception ignored) { | ||
return false; | ||
} | ||
} | ||
|
||
static By convertToCss(By by) { | ||
String className = extractClassName(by); | ||
if (className.contains(" ")) { | ||
throw new InvalidSelectorException( | ||
"Compound class names not supported in Firefox Shadow DOM. Use single class name or By.cssSelector instead." | ||
); | ||
} | ||
return By.cssSelector("." + className); | ||
} | ||
|
||
private static String extractClassName(By by) { | ||
String raw = by.toString().replace("By.className:", "").trim(); | ||
return raw.replaceAll("\\s+", ""); | ||
} | ||
|
||
public static By resolveForShadow(By by, SearchContext context) { | ||
return shouldUseCssSelector(by, context) ? convertToCss(by) : by; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would highly recommend not adding browser-specific logic here.