Javascript selenium webdriver将函数数组作为参数传递给executeScript

Javascript selenium webdriver将函数数组作为参数传递给executeScript,javascript,selenium-webdriver,webdriverjs,Javascript,Selenium Webdriver,Webdriverjs,这是错误的 import webdriver from 'selenium-webdriver'; const driver = new webdriver.Builder() .withCapabilities(webdriver.Capabilities.chrome()) .build(); driver.get('https://www.google.com'); let foo = function(rules) { ru

这是错误的

import webdriver from 'selenium-webdriver';

const driver = new webdriver.Builder()
              .withCapabilities(webdriver.Capabilities.chrome())
              .build();

driver.get('https://www.google.com');
let foo = function(rules) {
  rules.forEach(rule => {
    rule();
  });
}
let bar = function() { return 'bar' };
let baz = function() { return 'baz' };
driver.executeScript(foo, [bar, baz]).then(function(result) {
  console.log(result);
});

driver.quit();
函数似乎正在序列化为
字符串

WebDriverError: unknown error: rule is not a function


let foo = function(rules) {
  return rules;
  // rules.forEach(rule => {
  //   rule();
  // });
}
let bar = function() { return 'bar' };
let baz = function() { return 'baz' };
driver.executeScript(foo, [bar, baz]).then(function(result) {
  console.log(result); // refer the log pasted below
});
任何关于如何将函数数组作为参数传递的指针都会很有帮助。

问题: 所有作为参数传递给函数的非平凡数据都将转换为字符串,因为这是从selenium驱动程序向浏览器注入内容的唯一方法

参数必须是数字、布尔值、字符串、WebElement或上述任意组合的列表

解决方案 您可以将字符串转换为函数,并使用
eval
或函数构造函数
新函数(“…函数体在此…”)执行它。
。是的,这是一个非常糟糕的问题,但实际上,没有其他方法可以将非琐碎的数据从驱动程序传递到浏览器。实际上,当您调用这个
driver.executeScript(foo,[],…)
时,
foo
函数也会转换为字符串,并在浏览器中使用
eval
执行

如果我是你,我会尝试找到另一种方法来实现结果,而不将函数作为参数传递


您可以在以下位置阅读更多内容:

我认为您可以使用eval。见下面的代码:

[ 'function bar() {\n  return \'bar\';\n}',
  'function baz() {\n  return \'baz\';\n}' ]

我发现了一种不同的解决方法,不使用
eval
显式地,但方式类似

  • 要注入的函数必须是
  • 函数.toString()作为

  • 然后执行所需的函数,如下所示

    function foo(rules) {
      var result = [];
      rules.forEach(rule => {
        result.push(rule());
      });
      return result;
    }
    function bar() { return 'bar' };
    function baz() { return 'baz' };
    
    function inject(content) {
      var script = document.createElement('script');
      script.innerHTML = content;
      document.head.appendChild(script);
    }
    let script = `${bar.toString()} ${baz.toString()} ${foo.toString()}`;
    
    driver.executeScript(inject, script);
    

  • 完整示例

    driver.executeScript('return foo([bar, baz])').then(function(result) {
      // use the result
    });
    


    谢谢,我试过,
    eval
    new Function
    ,但都不起作用,很可能是我改变了实现。@TimurBilalov你说这很糟糕,我认为这是临时注入,只有在WebDriver显式注入时才会出现在测试环境的页面上,这是一种非常有效的测试策略。
    console.log(eval(rule))
    ,我不想记录函数,而是执行它。如何执行?我已经试过了。bar和baz都正确执行。你能再试一次吗?对于我来说,
    null
    被打印出来,请验证发布的代码和你正在执行的代码是相同的。顺便说一句,
    console.log(eval(rule))未返回任何值。我打算将其记录在浏览器控制台中。如果要在cmd或shell上获得结果,必须将每个求值的结果添加到列表中,然后返回它。@sarbbottam我已更新代码以返回结果数组。请看一看,让我知道它是否解决了您的问题。请阅读有关的评论。大家一致认为这种方法行不通/没有意义/是错误的。此外,WebDriver协议对JavaScript函数一无所知。
    
    driver.executeScript('return foo([bar, baz])').then(function(result) {
      // use the result
    });
    
    // example.js
    import webdriver from 'selenium-webdriver';
    
    const driver = new webdriver.Builder()
      .withCapabilities(webdriver.Capabilities.chrome())
      .build();
    
    driver.get('https://www.google.com');
    
    function foo(rules) {
      var result = [];
      rules.forEach(rule => {
        result.push(rule());
      });
      return result;
    }
    function bar() { return 'bar' };
    function baz() { return 'baz' };
    
    function inject(content) {
      var script = document.createElement('script');
      script.innerHTML = content;
      document.head.appendChild(script);
    }
    let script = `${bar.toString()} ${baz.toString()} ${foo.toString()}`;
    
    driver.executeScript(inject, script);
    
    driver.executeScript('return foo([bar, baz])').then(function(result) {
      console.log(result);
    });
    
    driver.quit();
    
    > babel-node example.js
    
    [ 'bar', 'baz' ]