Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Selenium(Node.js)屏幕截图太慢_Javascript_Node.js_Selenium_Mocha.js_Screenshot - Fatal编程技术网

Javascript Selenium(Node.js)屏幕截图太慢

Javascript Selenium(Node.js)屏幕截图太慢,javascript,node.js,selenium,mocha.js,screenshot,Javascript,Node.js,Selenium,Mocha.js,Screenshot,我正在使用Selenium+Mocha(在Node.js中)在一个站点上进行一些UI测试。每次测试后,我想截取一个屏幕截图,以便查看/共享可见结果 但是,在进行基本的UI更改(即插入文本并点击submit)之后,会触发一个AJAX调用+JavaScript动画,在此之后,我希望成为屏幕截图的一部分 我得到的截图似乎是在下一步已经开始后拍摄的。(因此,第一次测试运行>触发屏幕截图>第二次测试开始>屏幕截图被实际捕获) 我尝试了.sleep()和超时,但是我的使用可能是错误的 函数截图(name='

我正在使用Selenium+Mocha(在Node.js中)在一个站点上进行一些UI测试。每次测试后,我想截取一个屏幕截图,以便查看/共享可见结果

但是,在进行基本的UI更改(即插入文本并点击submit)之后,会触发一个AJAX调用+JavaScript动画,在此之后,我希望成为屏幕截图的一部分

我得到的截图似乎是在下一步已经开始后拍摄的。(因此,第一次测试运行>触发屏幕截图>第二次测试开始>屏幕截图被实际捕获)

我尝试了
.sleep()
和超时,但是我的使用可能是错误的

函数截图(name='out'){
driver.takeScreenshot().then(函数(数据){
var base64Data=data.replace(/^data:image\/png;base64,/,“”)
writeFile(`screenshots/${name}.png`,base64Data,'base64',函数(err){
if(err)console.log(err);
});
});
}
描述('UI测试',异步函数(){
before(异步函数(){
driver=wait new Builder().forBrowser('chrome').build();
等着司机,上车http://localhost:8000然后(异步函数(){await getAssets();});
/*搜索|提交|重置在getAssets()中声明*/
});
之后(异步函数(){
driver.quit();
});
afterEach(异步函数(){
step++;
司机,睡觉(3000),然后(
截图(步骤)
);
});
描述('用户类型/修改输入并提交查询',异步函数(){
它('键入搜索并单击提交',异步函数(){
搜索。发送密钥(“小狗和小猫”);
提交。单击();
});
它('单击X图标以清除搜索',异步函数(){
重置。单击();
});
});
});

在上面的代码片段中,第一个测试的屏幕截图(
“键入搜索并单击提交”
)将显示第二个测试中已清除的输入字段。

发送到selenium的命令是异步的,这意味着函数将安排工作在将来的某个时间运行,但会立即返回,以便代码继续运行

在selenium webdrivers的情况下,函数返回一个“承诺”,将在将来某个时候解决。摩卡可以用承诺等待结果

承诺和摩卡 Mocha使用测试的返回值来确定是否应该等待承诺的解决。您可以使用
等待
控制承诺流。然后

如果正在使用代码,那么在测试中总是要
返回someFormOfPromise

it(waits, function(){
  return Promise.resolve(true)
    .then(res => expect(res).to.be.true)
})
如果正在使用,则保证返回一个承诺,但必须执行任何异步操作,否则测试将继续进行

it(waits, async function(){
  let res = await Promise.resolve(true)
  expect(res).to.be.true
})
回调类似,但它们使用
done
函数来通知测试继续进行

it(waits, function(done){
  someTrueCallback((err, res) => {
    if (err) return done(err)
    expect(res).to.be.true
    done()
  }) 
})
在发布的代码中有很多混合代码,甚至有一个回调抛出。选择一种方法并尽可能坚持使用,我将使用/

收回承诺 任何异步回调都可以转换为承诺,因此从回调函数开始,将其转换为承诺:

function writeFile(path, data, format){
  return new Promise((resolve, reject)=>{
    fs.writeFile(path, data, format, function(err){
      if (err) return reject(err)
      resolve(true)
    })
  })
}
幸运的是,这是相当标准的,Node.js中有一个帮助程序,因此这些帮助程序可以成为:

const writeFile = util.promisify(fs.writeFile)

function async takeScreenshot(name='out'){
    let data = await driver.takeScreenshot()
    var base64Data = data.replace(/^data:image\/png;base64,/,"")
    return await writeFile(`screenshots/${name}.png`, base64Data, 'base64')
}
测验 无需使用
。然后在可用时使用

每当调用返回承诺的函数时,如果要使用解析值,可能需要使用
await
let res=await…

describe('UI Tests', function() {

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
    await driver.get('http://localhost:8000')
    await getAssets()
    /* search | submit | reset are declared in getAssets() */
  });

  after(async function() {
    await driver.quit();
  });

  afterEach(async function(){
    step++;
    await takeScreenshot(step) 
  });

  describe('User Types/Modifies Input and Submits Query', function() {

    it('type in search + click submit', async function(){
        await search.sendKeys("Puppies and Kittens");
        await submit.click();
    });

    it('click the X icon to clear search', async function(){
        await reset.click();
    });

  });

});

作为旁注,这些测试实际上并没有检查任何东西。通常情况下,将使用类似的断言库来确保事情按您的方式进行

谢谢你的精彩评论和解释:)我(显然)对测试有点生疏;所以我不确定分解测试的粒度——为了简单起见,我没有包括所有测试,但我确实有一些测试,它实际上检查预期值。不管怎样,我现在也在调查柴。再次谢谢你,不用担心。一旦async/promise工具单击所有节点,就会变得容易得多!