Implement global listener to pause code execution Implement global listener to pause code execution selenium selenium

Implement global listener to pause code execution


One solution which is a bit more complex than using a listener would be to wrap your element with a proxy and perform the check whenever you hit the proxy.

Let the listeners listen to events and not change the test's flow,

First of all we need to create a class that will perform the check whenever you call the element:

public class ElementProxy implements InvocationHandler {    private final WebElement element;    public ElementProxy(WebElement element) {        this.element = element;    }    @Override    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        this.waitForPageLoad();        return method.invoke(element, args);    }    private void waitForPageLoad() {        WebDriver driver = ((WrapsDriver) element).getWrappedDriver();        WebElement loadingBar = driver.findElement(By.xpath("//div[@class='ngx-loading-text center-center' and starts-with(., 'Loading')]"));        new WebDriverWait(driver, 20).until(ExpectedConditions.invisibilityOfElement(loadingBar))    }    public static WebElement proxy(WebElement element) {        ElementProxy proxy = new ElementProxy(element);        WebElement wrappdElement = (WebElement) Proxy.newProxyInstance(ElementProxy.class.getClassLoader(),                                                                       new Class[] { WebElement.class },                                                                       proxy);        return wrappdElement;    }    }

Then you can call ElementProxy.proxy(element) which will return a new proxied element, similar to the behavior of PageFactory under the hood.Last thing is to wrap it under your own PageFactory so you can control the behavior of the elements:

public class MyPageFactory {        public static <T> void initElements(WebDriver driver, T pageObject) {        PageFactory.initElements(driver, pageObject);                for (Field field : pageObject.getClass().getDeclaredFields()) {            if (field.getType().equals(WebElement.class)) {                boolean accessible = field.isAccessible();                field.setAccessible(true);                field.set(pageobject, ElementProxy.proxy((WebElement) field.get(pageObject)));                field.setAccessible(accessible);            }          }    }    }

Now if you are in a web-page where the loading-bar is present, use your new MyPageFactory, which will perform the check automatically.

If you do not need to perform the check, use the regular PageFactory.

Reference: https://www.vinsguru.com/selenium-webdriver-how-to-handle-annoying-random-popup-alerts/


There is a WebDriverEventListener that can accomplish what you want. You could implement this listener such that before each command executed by selenium, the listener checks for the visibilityOfElementLocated(By.xpath("//div[@class='ngx-loading-text center-center' and starts-with(., 'Loading')]")));, and if so execute your WebDriverWait. Without seeing your code I'm not sure exactly how you'd implement this, but here's a resource with some good examples.

http://toolsqa.com/selenium-webdriver/event-listener/