Selenium: Watching for a dom event while executing other actions

后端 未结 1 398
时光取名叫无心
时光取名叫无心 2021-01-26 07:38

Using Selenium I need to validate that an element, as it is dragged across the window, will trigger a \'drop zone\' and then release that element in the zone. I can drag the el

相关标签:
1条回答
  • 2021-01-26 08:12

    It took awhile, but I finally figure out how to watch with MutationObservers. However, I have yet to apply it to a 'drag and drop'.

    Once I know which node I need to watch for a change, in most cases if a node is added or removed, I can inject a MutationObserver. I ended up creating a class for all my MO work.

    namespace Framework.Utilities
    {
    public class Watcher
    {
        private static IWebDriver _driver;
    
        public Watcher(Driver driver) { this.driver = driver; }
    
        public void WatchBody() {
            var mutationObserverScript = @”(function (){     
                var myObserver = window.document.MutationObserver || {};     
                    window.myObserver = {
                        observer: new MutationObserver(function (mutationsList) {
                            for (let mutation of mutationsList) {
                                if (mutation.addedNodes.length >= 1) {
                                    myObserver.occured = true;
                                    myObserver.observer.disconnect();
                                }
                            }
                        }),
                    occurred: false
                };
                var config = {childList: true};
                var element = document.querySelector(‘boy’);
                window. myObserver.observer.observe(element, config);});"; 
    
            JavascriptExecutor js = (JavascriptExecutor) driver;  
            js.executeScript(mutationObserverScript);
        }
        public bool WaitForChange()
        {
            var results = defaultWait.Until( driver1 =>  ((IJavaScriptExecutor)_driver).ExecuteScript("returnwindow.myObserver.occurred;").Equals(true));
            return results;
        }       
    
        public bool AffectWith(Action watcher, Action action)
        {
            watcher();
            action();
            return WaitForChange();
        }
    }
    }
    

    Some of the above will look familiar. I pulled in various pieces from a variety of postings on the internet.

    My use case is watching for an overlay modal to appear:

    Instantiate the Watcher class

    var watcher = new Watcher(driver);
    

    Setup the action

    var myBtn = driver.FindElement(By.CssSelector(buttonSelector));
    Action clickButton = () => myBtn.Click();
    

    Observe for the change

    if(watcher.AffectWith(watcher.WatchBody, clickButton)) 
    {
        <detected modal is gone, keep testing>
    }
    else 
    { 
        <problems with modal> 
    }
    

    From what I've read, they work well since MutationObservers are executed the same as a ‘Promise’, they are a microtask and are executed before the next task in the DOM. By watching for the ‘flip to true’, I also know that any ‘async’ Microtask Angular call has completed as well.

    Of note, disconnecting an observer will not remove it, a good practice it to set it to null. And, by including the ‘{}’ when defining the MutationObserver, you can index it. This prevents multiple MutationObservers from resetting parameters while another one is still active.

    0 讨论(0)
提交回复
热议问题