Showing posts with label Selenium. Show all posts
Showing posts with label Selenium. Show all posts

2020-10-10

Web Components Selenium test automation

The one of strengths of Web Components is shadow DOM. It allows to insulate the css rules scoping to own content, allows efficient memory use by sharing DOM, etc... But for QA folks it could make a challenge as usual CSS and XPath selectors would not work anymore. There is a way around.

Elements in Shadow DOM are not available via direct CSS or XPath. Instead you could use JS selector via "Copy JS path":

In this case the full selector is

full selector
document.querySelector("#container-a593f6c588 > div > div > div > div > div > shopping-list")
.shadowRoot.querySelector("div.padded > vaadin-combo-box")
.shadowRoot.querySelector("#input")
.shadowRoot.querySelector("#vaadin-text-field-label-0")

which could be shortened to 

trimmed selector
document.querySelector("shopping-list")
.shadowRoot.querySelector("vaadin-combo-box")
.shadowRoot.querySelector("#input")
.shadowRoot.querySelector("#vaadin-text-field-label-0")


For simplification in styles tables the series of CSS selectors and shadowRoot could be swapped with :shadow-root pseudoselector. CSS handler in this case should convert the string bello to JS above:

pseudo selector :shadow-root
jkp-shop-plans :shadow-root vaadin-combo-box :shadow-root #input :shadow-root #vaadin-text-field-label-0

the "Element locator" css should sniff for ":shadow-root" sub-string and replace with JS sequence above returning JS object. WebDriver has a By.js locator only in JS webdriver implementation. In Java you have to simulate it yourself. Fortunately that is easy via js Executor:

  1. String javascript = "document.querySelector('vaadin-combo-box').shadowRoot.querySelector('#input').shadowRoot.querySelector('#vaadin-text-field-label-0')";  
  2. JavascriptExecutor jsExecutor = (JavascriptExecutor) driver;  
  3. WebElement element = (WebElement) jsExecutor.executeScript(javascript); 



2020-08-07

How to check for existence of element by webDriver fast?

Simple answer: by JS evaluation. 
In given samples the Selenium performance almost twice over webDriver.findElements(). 

Cluecumner report on timing: 



Test .feature file:

And test element presence "50000" times by findElements
And test element presence "50000" times by js 

Java code 


@And("^test element presence \"(.*?)\" times by findElements")
public void testElement(String n) {
int number = Integer.parseInt(n);
for (int index = 0; index < number; index++) {
List<WebElement> list = webDriver.findElements(By.cssSelector("coral-multifield-item,a[fake=\""+n+"\"]"));
assert( list.size()>0 );
}
}
@And("^test element presence \"(.*?)\" times by js")
public void testElementByJs(String n) {
int number = Integer.parseInt(n);
for (int index = 0; index < number; index++) {
JavascriptExecutor js = (JavascriptExecutor) webDriver;
String o =(String)js.executeScript("return ''+!!document.querySelector('coral-multifield-item,a[fake=\""+n+"\"]')");

assert( "true".equals(o) );
}
}