0

Question :

Based on : QAF | Passing new locator on failure

Trying to update the element onFailure method. Using OrangeHRM site to test and trying to fill the password value.

during the test locator value is : id = "txtpassword1" [ which is a wrong one ] OnFailure trying to set it to id = "txtpassword" [ correct id ]

but QAF is not updating the element and the test fails.

   public void onFailure(QAFExtendedWebElement element, CommandTracker commandTracker ) {
       
           System.out.println("=====<<<<<<< FALLBACK element >>>>>>>------>  \n" + element);
           System.out.println("=====<<<<<<< FALLBACK commandTracker >>>>>>>------> \n " +commandTracker);
           
           element.setBy(By.id("txtPassword"));
           //element.setId("txtPassword");
           commandTracker.setRetry(true);
           
           System.out.println("=====<<<<<<< FALLBACK after element >>>>>>>------>  \n" + element);
           System.out.println("=====<<<<<<< FALLBACK after commandTracker >>>>>>>------> \n " + commandTracker);
           }

Console output :


=====<<<<<<< FALLBACK element >>>>>>>------>  
Using any of[id=txtPassword1]
=====<<<<<<< FALLBACK commandTracker >>>>>>>------> 
com.qmetry.qaf.automation.ui.webdriver.CommandTracker@3a8d467e
=====<<<<<<< FALLBACK after element >>>>>>>------>  
Using any of[id=txtPassword1]
=====<<<<<<< FALLBACK after commandTracker >>>>>>>------> 
com.qmetry.qaf.automation.ui.webdriver.CommandTracker@3a8d467e
18:03:18.104 [main] ERROR com.qmetry.qaf.automation.step.TestStepListener - Failure Teststep: And I fill password "admin123" into "test.loc.Password" with arguments: [admin123,test.loc.Password]
org.openqa.selenium.TimeoutException: Timed out after 30 seconds waiting for presence of element located by: Using any of[id=txtPassword1]

Noticed that element value is same even after element.setby

######################## -- UPDATED CODE -- ############################ rt_retrylistner.java file

package com.rt.listener;

import org.openqa.selenium.By;
import com.qmetry.qaf.automation.core.QAFListenerAdapter;
import com.qmetry.qaf.automation.ui.webdriver.CommandTracker;
import com.qmetry.qaf.automation.ui.webdriver.QAFExtendedWebDriver;
import com.qmetry.qaf.automation.util.JSONUtil;
import com.qmetry.qaf.automation.util.LocatorUtil;
import java.util.HashMap;
import java.util.Map;

//public class rt_retrylistener extends QAFWebElementCommandAdapter  
public class rt_retrylistener extends QAFListenerAdapter {

    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)

    {
        System.out.println("into on failure ");

        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 = By.id("txtpassword");
            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;

    }


}

Have enabled the listener in application.properties wd.command.listeners=com.rt.listener.rt_retrylistener

Error message from console :

14:29:16.132 [main] ERROR com.qmetry.qaf.automation.step.TestStepListener - Failure Teststep: And I fill password "admin123" into "Password||rt.loc.3EPsPFPj9" with arguments: [admin123, Password||rt.loc.3EPsPFPj9]
java.lang.NullPointerException: Cannot invoke "com.qmetry.qaf.automation.ui.webdriver.QAFExtendedWebElement.setBy(org.openqa.selenium.By)" because "element" is null
    at com.rt.steps.rt_globals.iFillPasswordInTo(rt_globals.java:837) ~[test-classes/:?]
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[?:?]
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
    at java.lang.reflect.Method.invoke(Method.java:568) ~[?:?]
    at com.qmetry.qaf.automation.step.JavaStep.doExecute(JavaStep.java:150) ~[qaf-3.0.1.jar:?]
    at com.qmetry.qaf.automation.step.BaseTestStep.execute(BaseTestStep.java:149) [qaf-3.0.1.jar:?]
    at com.qmetry.qaf.automation.step.StringTestStep.execute(StringTestStep.java:127) [qaf-3.0.1.jar:?]
    at com.qmetry.qaf.automation.step.client.Scenario.execute(Scenario.java:174) [qaf-3.0.1.jar:?]
    at com.qmetry.qaf.automation.step.client.Scenario.scenario(Scenario.java:237) [qaf-3.0.1.jar:?]
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[?:?]
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
    at java.lang.reflect.Method.invoke(Method.java:568) ~[?:?]
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:104) [testng-6.10.jar:?]
    at org.testng.internal.Invoker.invokeMethod(Invoker.java:645) [testng-6.10.jar:?]
    at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:851) [testng-6.10.jar:?]
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1177) [testng-6.10.jar:?]
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:129) [testng-6.10.jar:?]
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:112) [testng-6.10.jar:?]
    at org.testng.TestRunner.privateRun(TestRunner.java:756) [testng-6.10.jar:?]
    at org.testng.TestRunner.run(TestRunner.java:610) [testng-6.10.jar:?]
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:387) [testng-6.10.jar:?]
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:382) [testng-6.10.jar:?]
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:340) [testng-6.10.jar:?]
    at org.testng.SuiteRunner.run(SuiteRunner.java:289) [testng-6.10.jar:?]
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52) [testng-6.10.jar:?]
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86) [testng-6.10.jar:?]
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1293) [testng-6.10.jar:?]
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1218) [testng-6.10.jar:?]
    at org.testng.TestNG.runSuites(TestNG.java:1133) [testng-6.10.jar:?]
    at org.testng.TestNG.run(TestNG.java:1104) [testng-6.10.jar:?]
    at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:122) [surefire-testng-2.9.jar:2.9]
    at org.apache.maven.surefire.testng.TestNGXmlTestSuite.execute(TestNGXmlTestSuite.java:92) [surefire-testng-2.9.jar:2.9]
    at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:101) [surefire-testng-2.9.jar:2.9]
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[?:?]
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
    at java.lang.reflect.Method.invoke(Method.java:568) ~[?:?]
    at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:164) [surefire-api-2.9.jar:2.9]
    at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:110) [surefire-booter-2.9.jar:2.9]
    at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:172) [surefire-booter-2.9.jar:2.9]
    at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcessWhenForked(SurefireStarter.java:104) [surefire-booter-2.9.jar:2.9]
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:70) [surefire-booter-2.9.jar:2.9]
Feb 11, 2022 2:29:16 PM org.openqa.selenium.os.ProcessUtils killWinProcess
WARNING: Process refused to die after 10 seconds, and couldn't taskkill it
java.lang.RuntimeException: Couldn't detect pid
    at org.openqa.selenium.os.ProcessUtils.getProcessId(ProcessUtils.java:194)
    at org.openqa.selenium.os.ProcessUtils.killWinProcess(ProcessUtils.java:127)
    at org.openqa.selenium.os.ProcessUtils.killProcess(ProcessUtils.java:80)
    at org.openqa.selenium.os.UnixProcess$SeleniumWatchDog.destroyHarder(UnixProcess.java:265)
    at org.openqa.selenium.os.UnixProcess$SeleniumWatchDog.access$200(UnixProcess.java:219)
    at org.openqa.selenium.os.UnixProcess.destroy(UnixProcess.java:127)
    at org.openqa.selenium.os.CommandLine.destroy(CommandLine.java:153)
    at org.openqa.selenium.remote.service.DriverService.stop(DriverService.java:220)
    at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:95)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:586)
    at com.qmetry.qaf.automation.ui.webdriver.QAFExtendedWebDriver.execute(QAFExtendedWebDriver.java:236)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:643)
    at com.qmetry.qaf.automation.ui.webdriver.QAFExtendedWebDriver.execute(QAFExtendedWebDriver.java:224)
    at org.openqa.selenium.remote.RemoteWebDriver.quit(RemoteWebDriver.java:482)
    at com.qmetry.qaf.automation.ui.webdriver.QAFExtendedWebDriver.stop(QAFExtendedWebDriver.java:611)
    at com.qmetry.qaf.automation.ui.UiDriverFactory.tearDown(UiDriverFactory.java:96)
    at com.qmetry.qaf.automation.core.QAFTestBase.tearDown(QAFTestBase.java:184)
    at com.qmetry.qaf.automation.ui.AbstractTestBase.tearDown(AbstractTestBase.java:103)
    at com.qmetry.qaf.automation.ui.AbstractTestCase.tearDownPrrallelThreads(AbstractTestCase.java:87)
    at com.qmetry.qaf.automation.ui.AbstractTestCase.afterTest(AbstractTestCase.java:77)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:104)
    at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:515)
    at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:217)
    at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:144)
    at org.testng.TestRunner.afterRun(TestRunner.java:983)
    at org.testng.TestRunner.run(TestRunner.java:614)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:387)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:382)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:340)
    at org.testng.SuiteRunner.run(SuiteRunner.java:289)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1293)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1218)
    at org.testng.TestNG.runSuites(TestNG.java:1133)
    at org.testng.TestNG.run(TestNG.java:1104)
    at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:122)
    at org.apache.maven.surefire.testng.TestNGXmlTestSuite.execute(TestNGXmlTestSuite.java:92)
    at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:101)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:164)
    at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:110)
    at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:172)
    at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcessWhenForked(SurefireStarter.java:104)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:70)
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field private final long java.lang.ProcessImpl.handle accessible: module java.base does not "opens java.lang" to unnamed module @382db087
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
    at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:178)
    at java.base/java.lang.reflect.Field.setAccessible(Field.java:172)
    at org.openqa.selenium.os.ProcessUtils.getProcessId(ProcessUtils.java:180)
    ... 51 more

14:29:16.980 [main] ERROR com.qmetry.qaf.automation.ui.WebDriverCommandLogger - command: quit[ param-1: {}] Result: Error communicating with the remote browser. It may have died.
Build info: version: '3.6.0', revision: '6fbf3ec767', time: '2017-09-27T15:28:36.4Z'
System info: host: 'MAVCHN1121100', ip: '192.168.1.3', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '17.0.1'
Driver info: driver.version: QAFExtendedWebDriver
Capabilities [{networkConnectionEnabled=false, chrome={chromedriverVersion=97.0.4692.71 (adefa7837d02a07a604c1e6eff0b3a09422ab88d-refs/branch-heads/4692@{#1247}), userDataDir=C:\Users\C6D43~1.KAR\AppData\Local\Temp\scoped_dir41280_431193466}, timeouts={implicit=0, pageLoad=300000, script=30000}, pageLoadStrategy=normal, unhandledPromptBehavior=dismiss and notify, strictFileInteractability=false, platform=WINDOWS, proxy=Proxy(), goog:chromeOptions={debuggerAddress=localhost:51187}, webauthn:extension:credBlob=true, acceptInsecureCerts=false, browserVersion=97.0.4692.99, browserName=chrome, javascriptEnabled=true, platformName=WINDOWS, setWindowRect=true, webauthn:extension:largeBlob=true, webauthn:virtualAuthenticators=true}]
Session ID: 7b06a2cc937bfa016f82089896f3c354
into on failure 
14:29:16.980 [main] ERROR com.qmetry.qaf.automation.ui.UiDriverFactory - Error communicating with the remote browser. It may have died.
Build info: version: '3.6.0', revision: '6fbf3ec767', time: '2017-09-27T15:28:36.4Z'
System info: host: 'MAVCHN1121100', ip: '192.168.1.3', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '17.0.1'
Driver info: driver.version: QAFExtendedWebDriver
Capabilities [{networkConnectionEnabled=false, chrome={chromedriverVersion=97.0.4692.71 (adefa7837d02a07a604c1e6eff0b3a09422ab88d-refs/branch-heads/4692@{#1247}), userDataDir=C:\Users\C6D43~1.KAR\AppData\Local\Temp\scoped_dir41280_431193466}, timeouts={implicit=0, pageLoad=300000, script=30000}, pageLoadStrategy=normal, unhandledPromptBehavior=dismiss and notify, strictFileInteractability=false, platform=WINDOWS, proxy=Proxy(), goog:chromeOptions={debuggerAddress=localhost:51187}, webauthn:extension:credBlob=true, acceptInsecureCerts=false, browserVersion=97.0.4692.99, browserName=chrome, javascriptEnabled=true, platformName=WINDOWS, setWindowRect=true, webauthn:extension:largeBlob=true, webauthn:virtualAuthenticators=true}]
Session ID: 7b06a2cc937bfa016f82089896f3c354
user1231
  • 1
  • 1

1 Answers1

0

in order to handle find element failure use onFailure from driver listener:

package myapp.listener;
...
public class QAFListenerImpl extends QAFListenerAdapter{
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;

    }
}

register listener using qaf.listeners property, for this example it will be

qaf.listeners=myapp.listener.QAFListenerImpl
user861594
  • 5,733
  • 3
  • 29
  • 45
  • Thanks - user861594 but still the code is showing error on line : @ Override public void onFailure(QAFExtendedWebDriver driver, CommandTracker commandTracker) showing error to remove @ Override. if i remove not entering into onFailure method. If i use QAFExtendedWebElement element then @Override is getting accepted. – user1231 Feb 09 '22 at 11:27
  • -user861594 Using QAF 3.0.1 and also tried by downgrade to QAF 3.0.0. Please find the updated code on question edit. – user1231 Feb 09 '22 at 11:40
  • error may be because you don't implemented driver listener. Refer [qaf listeners](https://qmetry.github.io/qaf/latest/qaf_listeners.html) Either implement `QAFWebDriverCommandListener` or extend `QAFWebDriverCommandAdapter`. Check updated answer. Also user qaf version 3.0.1 or later. As of today [latest version](https://mvnrepository.com/artifact/com.qmetry/qaf) is 3.1.0-RC2 – user861594 Feb 09 '22 at 23:37
  • Thanks for your response. @ Override issue got resolved by extending QAFWebDriverCommandAdapter but onFailure method is not getting called //public class rt_retrylistener implements QAFWebDriverCommandListener { public class rt_retrylistener extends QAFWebDriverCommandAdapter @Override public void onFailure(QAFExtendedWebDriver driver, CommandTracker commandTracker) { System.out.println(" into on failure method ") ; } } tried with both options – user1231 Feb 10 '22 at 10:28
  • but onFailure method is getting called on public class rt_retrylistener extends QAFWebElementCommandAdapter { @Override public void onFailure(QAFExtendedWebElement element, CommandTracker commandTracker ) { System.out.println(" into on failure method ") ; } Kindly suggest. – user1231 Feb 10 '22 at 10:29
  • the method you are using is of element listener, instead you need to use from driver listener. Refer and follow the answer. Make sure that you have register the driver listener class. you can remove element onfailure method – user861594 Feb 10 '22 at 18:10
  • Thanks for your message. Still I'm not able to solve the issue. Listener is getting triggered but element is not getting passed onto the driver. Have update the code with all information. kindly let me know if more information is need. – user1231 Feb 11 '22 at 09:16