【问题标题】:Selenium: Watching for a dom event while executing other actionsSelenium:在执行其他操作时监视 dom 事件
【发布时间】:2018-09-20 14:54:04
【问题描述】:

使用 Selenium,我需要验证一个元素,当它被拖过窗口时,将触发一个“放置区”,然后在该区域中释放该元素。我可以将元素拖动到整个页面,但需要确定何时将“放置区”元素添加到 dom 中,以便我知道我可以释放该元素。

我已经查看了“Mutation Observers”,这将是完美的,除非观察者在回调执行之前不会返回。我不能在等待 Dom 发生变化的同时拖动元素,可以吗?

最初,我以为我可以为节点设置一个非常具体的观察者并退出异步javascript调用,然后在检查回调结果之前执行拖放操作。但是,脚本在回调之前不会退出并返回。第 22 条军规!我不能在观看的同时拖放。帮助?

我有几个测试用例,我需要在执行其他操作的同时监视特定事件,并且 selenium 驱动程序是单线程。有人有什么想法吗?

【问题讨论】:

  • 当一个元素在它的顶部时,你能不考虑对 dropzone 容器进行回调吗?很难描述,但基本上类似于:jqueryui.com/droppable/#accepted-elements 如果需要在您的页面上通过 JavaScript 进行设置?
  • 您应该从用户的角度通过断言 DOM 的结果结构/内容来验证 drop。也就是说,可以使用executeAsyncScript 处理回调。

标签: selenium observers mutation


【解决方案1】:

花了一段时间,但我终于弄清楚如何使用 MutationObservers 进行观看。但是,我还没有将它应用到“拖放”中。

一旦我知道我需要监视哪个节点以进行更改,在大多数情况下,如果添加或删除了一个节点,我就可以注入一个 MutationObserver。我最终为我所有的 MO 工作创建了一个类。

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();
    }
}
}

上面的一些内容看起来很熟悉。我从互联网上的各种帖子中提取了各种片段。

我的用例正在观察是否出现覆盖模式:

实例化观察者类

var watcher = new Watcher(driver);

设置动作

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

观察变化

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

根据我的阅读,它们运行良好,因为 MutationObserver 的执行方式与“Promise”相同,它们是一个微任务,在 DOM 中的下一个任务之前执行。通过观察“flip to true”,我还知道任何“异步”Microtask Angular 调用也已完成。

值得注意的是,断开观察者的连接不会将其删除,最好将其设置为 null。而且,通过在定义 MutationObserver 时包含“{}”,您可以对其进行索引。这可以防止多个 MutationObserver 在另一个仍处于活动状态时重置参数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-23
    • 1970-01-01
    • 2016-05-24
    • 1970-01-01
    • 2015-05-12
    • 1970-01-01
    相关资源
    最近更新 更多