如何同步注入脚本?

时间:2013-09-04 22:26:51

标签: javascript selenium-webdriver

许多人建议我只使用.onload并在脚本准备好后触发回调。这对我不起作用。我正在写一个函数,它希望一个元素立即,而不是以后。这就是我所拥有的:

webdriver.By.sizzle = function(selector) {
    driver.executeScript("if(typeof Sizzle==='undefined'){var s=document.createElement('script');s.type='text/javascript';s.src='https://raw.github.com/jquery/sizzle/master/src/sizzle.js';document.head.appendChild(s);}");
    return new webdriver.By.js("return Sizzle('"+selector.replace(/"/g,'\\"')+"')[0]");
};

我想注入Sizzle(如果它尚未包含),然后返回HtmlElement。如果需要,它可以忙等待,但它必须返回一个HtmlElement。

所有answers here基本上只是说'#34;不做'#34;但我无法想到另一种方式。

这是用于JavaScript的selenium web驱动程序的选择器。


driver.executeScript会接受争论。我想知道我是否可以传入webdriver.promise并在加载脚本时调用它?我不知道如何填补'承诺。

3 个答案:

答案 0 :(得分:2)

这里最好的选择是重新设计/重构代码以处理Sizzle的异步加载并通过回调函数返回结果。这就是javascript的设计方式。它没有“同步”加载远程资源的“好方法”。

我知道同步加载远程资源(如JS文件)的唯一方法是使用阻塞的AJAX调用来加载资源(将受到相同的源限制,因此您必须在服务器上托管它)和然后,一旦将资源加载到内存中,就可以执行它(导致它被加载)。然后,您可以调用其中定义的函数并返回其结果。

这很糟糕的原因是阻塞ajax调用会在加载远程资源时锁定浏览器一段不确定的时间。这种设计对用户体验不利。


我能想到的唯一另一个选择是在页面加载期间确保已经指定了所有必需的资源,以便在脚本需要时已经预加载它们。按需加载远程资源是导致异步问题的原因。

答案 1 :(得分:0)

为什么不将sizzle作为页面脚本要求包含在内。坚持

<script src="sizzle.js"></script>

头部的某个地方,它会在你的其他脚本运行之前加载。要动态执行此操作,只需将脚本附加到头部即可。 http://jsfiddle.net/nQePg有一个演示器,可以在解析和评估注入时显示脚本执行暂停。

答案 2 :(得分:0)

这有点慢,但我想我找到了一个解决方案:

webdriver.By.sizzle = function(selector) {
    driver.executeScript("return typeof Sizzle==='undefined'").then(function(noSizzle) {
        if(noSizzle) driver.executeScript(fs.readFileSync('sizzle.min.js', {encoding: 'utf8'}));
    });
    return new webdriver.By.js("return Sizzle('"+selector.replace(/"/g,'\\"')+"')[0]");
};

我刚刚下载了脚本,我正在内联注入整个内容。这样我就不需要等待任何事情。