QAF discourage to use static class variable for driver. The code provided in question will not work for parallel execution. Driver management is taken care by qaf with thread safety and with different behavior that can be set using property selenium.singletone
.
You can try following way when you want SelfHealingDriver:
public class SampleTest extends WebDriverTestCase {
@Test
public void yourTestCase(){
SelfHealingDriver driver = SelfHealingDriver.create(getDriver());
//your code goes below
}
}
SelfHealingDriver proxies actual driver. You can achieve the self heal functionality without driver proxy with listener for findelement/findChildelement. Driver listener should work without proxing driver. For example:
public class WDListener extends QAFWebDriverCommandAdapter {
private static final Map<String, Object> byToString = JSONUtil.toMap(
"{'ByCssSelector':'css selector','ByClassName':'class name','ByXPath':'xpath','ByPartialLinkText':'partial link text','ById':'id','ByLinkText':'link text','ByName':'name'}");
//this method will called when new driver object created
public void onInitialize(QAFExtendedWebDriver driver){
driver.manage().timeouts().implicitlyWait(4, TimeUnit.SECONDS);
driver.manage().window().setSize(new Dimension(1200, 800));
}
@Override
public void afterCommand(QAFExtendedWebDriver driver, CommandTracker commandTracker) {
if (DriverCommand.FIND_ELEMENT.equalsIgnoreCase(commandTracker.getCommand())
|| DriverCommand.FIND_ELEMENTS.equalsIgnoreCase(commandTracker.getCommand())
|| DriverCommand.FIND_CHILD_ELEMENT.equalsIgnoreCase(commandTracker.getCommand())
|| DriverCommand.FIND_CHILD_ELEMENTS.equalsIgnoreCase(commandTracker.getCommand())) {
Map<String, Object> parameters = commandTracker.getParameters();
if (parameters != null && parameters.containsKey("using") && parameters.containsKey("value")) {
By by = LocatorUtil
.getBy(String.format("%s=%s", parameters.get("using"), parameters.get("value")));
HealingServiceImpl healingServiceImpl = new HealingServiceImpl(new SelfHealingEngine(driver));
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
Object result = commandTracker.getResponce().getValue();
List<WebElement> webElements = List.class.isAssignableFrom(result.getClass())?(List<WebElement>) result:Collections.singletonList((WebElement)result)
healingServiceImpl.savePath(new PageAwareBy(driver.getTitle(),by),webElements);
}
}
}
@Override
public void onFailure(QAFExtendedWebDriver driver, CommandTracker commandTracker) {
// StackTraceElement[] stackTrace =
// commandTracker.getException().getStackTrace();
Map<String, Object> parameters = commandTracker.getParameters();
if (parameters != null && parameters.containsKey("using") && parameters.containsKey("value")) {
By by = LocatorUtil
.getBy(String.format("%s=%s", parameters.get("using"), parameters.get("value")));
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
HealingServiceImpl healingServiceImpl = new HealingServiceImpl(new SelfHealingEngine(driver));
Optional<By> healedBy = healingServiceImpl.healLocators(new PageAwareBy(driver.getTitle(),by), null, stackTrace) ;
if(healedBy.isPresent()) {
commandTracker.getParameters().putAll(toParams(healedBy.get()));
commandTracker.setRetry(true);
}
}
}
}