javaselenium-webdriverqaf

QAF | Passing new locator on failure


During locator failure, I want to pass a newly generated locator on the fly. I'm aware of the QAF's inbuilt multiple locator strategy but in my case locator may change during the run so I will not get new locator info before the run.


Solution

  • with qaf 3.0.1 you can set by in QAFExtendedWebElement. Best way is to use element listener. For example

    @Override
    public void onFailure(QAFExtendedWebElement element, CommandTracker commandTracker) {
        //By newBy = <do needful>;
        element.setBy(newBy);
        commandTracker.setRetry(true);
    }
    

    qaf 3.0.1b is released, you can try that.

    EDIT: to handle find element failure you can use driver listener. For example:

       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'}");
    
        @Override
        public void onFailure(QAFExtendedWebDriver driver, CommandTracker commandTracker) {
    
            Map<String, Object> parameters = commandTracker.getParameters();
            if (parameters != null && parameters.containsKey("using") && parameters.containsKey("value")) {
                By actaulBy = LocatorUtil.getBy(String.format("%s=%s", parameters.get("using"), parameters.get("value")));
                By newBy = <do the needful>
                commandTracker.getParameters().putAll(toParams(newBy));
                commandTracker.setRetry(true);
            }
        }
    
        private static Map<String, String> toParams(By by) {
            Map<String, String> map = new HashMap<String, String>();
            String val = by.toString().split(":", 2)[1].trim();
            map.put("using", byToString.get(by.getClass().getSimpleName()).toString());
            map.put("value", val);
    
            return map;
    
        }