2017-04-24 97 views
2

我正在使用Electron + Nightmare.js进行单元测试。是否可以复制/粘贴电子?

我需要将字符串复制到clibboard> focus a element>粘贴内容。然后测试是关于如果我的JavaScript处理正常。

我在电子文档阅读有关clipboard api, 和copy/paste in webview,但不知道如何与Nightmare.js API集成,大概在.actionsuggested in this issue

一个例子是:

import nightmare from 'nightmare' 
nightmare.action('copyPaste', function(name, options, parent, win, renderer, done) { 
    // some magic here 
}); 

// and then 

let res = await page 
    .wait('.my-element-to-render') 
    .copyPaste(blob) 
    .evaluate(() => { 
     return document.querySelector('.my-element').value; 
    }).end(); 
expect(res).to.equal('my pasted string'); 

任何指针或经验,用这个?

从我得到的参数nightmare.action什么是相当于<webview>所以我可以调用它的复制/粘贴方法?

回答

0

复制/粘贴在Electron中不起作用。这是由于缺少应用程序的键盘绑定到本地剪贴板的菜单。你可以用JS的这段代码修复它。

您还应该检出此GitHub存储库 - 它的一个干净的HowTo如何解决这个问题。

CODESNIPPET

var app = require("app"); 
var BrowserWindow = require("browser-window"); 
var Menu = require("menu"); 
var mainWindow = null; 

app.on("window-all-closed", function(){ 
    app.quit(); 
}); 

app.on("ready", function() { 
    mainWindow = new BrowserWindow({ 
     width: 980, 
     height: 650, 
     "min-width": 980, 
     "min-height": 650 
    }); 
    mainWindow.openDevTools(); 
    mainWindow.loadUrl("file://" + __dirname + "/index.html"); 
    mainWindow.on("closed", function() { 
     mainWindow = null; 
    }); 

    // Create the Application's main menu 
    var template = [{ 
     label: "Application", 
     submenu: [ 
      { label: "About Application", selector: "orderFrontStandardAboutPanel:" }, 
      { type: "separator" }, 
      { label: "Quit", accelerator: "Command+Q", click: function() { app.quit(); }} 
     ]}, { 
     label: "Edit", 
     submenu: [ 
      { label: "Undo", accelerator: "CmdOrCtrl+Z", selector: "undo:" }, 
      { label: "Redo", accelerator: "Shift+CmdOrCtrl+Z", selector: "redo:" }, 
      { type: "separator" }, 
      { label: "Cut", accelerator: "CmdOrCtrl+X", selector: "cut:" }, 
      { label: "Copy", accelerator: "CmdOrCtrl+C", selector: "copy:" }, 
      { label: "Paste", accelerator: "CmdOrCtrl+V", selector: "paste:" }, 
      { label: "Select All", accelerator: "CmdOrCtrl+A", selector: "selectAll:" } 
     ]} 
    ]; 

    Menu.setApplicationMenu(Menu.buildFromTemplate(template)); 
}); 
+0

感谢您检查这个!你能指出我可以如何将它与nightmare.js整合吗?什么是'应用程序'看npm我找到一个旧的模块,从Github消失。 – Sergio

+0

管理得到它实际上工作。并发布了一个答案。再次感谢您检查! – Sergio

+0

对我不起作用 '错误:无法找到模块'menu'' –

4

好了,以后多小时得到它的工作!

诀窍是使用Nightmare.js可以模拟的click事件,并使用它触发浏览器中的复制和粘贴。

复制/粘贴的逻辑是:

.evaluate((blob) => { 
    var editor = document.querySelector('.the-element-to-paste-to'); 
    editor.innerHTML = ''; // so we have a clean paste 
    window.addEventListener('copy', function (e){ // this will fire because of "document.execCommand('copy')" 
     e.clipboardData.setData('text/html', blob); 
     e.preventDefault(); 
     return false; 
    }); 
    var mockClick = document.createElement('button'); 
    mockClick.id = 'mockClick'; 
    mockClick.addEventListener('click', function(e){ // this will fire first 
     document.execCommand("copy"); 
     editor.focus(); 
     document.execCommand('paste'); 
    }); 
    document.body.appendChild(mockClick); 
}, myTextThatIWantToPaste) 

Nightmare.js将触发点击的照顾,然后我们得到我们自己的文本复制/粘贴。

我的整个测试是像现在这样:

it('should handle pasted test', async function() { 
    let page = visit('/index.html'); 
    let res = await page 
     .wait('.the-element-to-paste-to') 
     .evaluate((blob) => { 
      var editor = document.querySelector('.the-element-to-paste-to'); 
      editor.innerHTML = ''; // so we have a clean paste 
      window.addEventListener('copy', function (e){ 
       e.clipboardData.setData('text/html', blob); 
       e.preventDefault(); 
       return false; 
      }); 
      var mockClick = document.createElement('button'); 
      mockClick.id = 'mockClick'; 
      mockClick.addEventListener('click', function(e){ 
       document.execCommand("copy"); 
       editor.focus(); 
       document.execCommand('paste'); 
      }); 
      document.body.appendChild(mockClick); 
     }, tableBlob) 
     .click('#mockClick') // <---- this is the trigger to the click 
     .wait(100) 
     .evaluate(() => { 
      var editor = document.querySelector('.the-element-to-paste-to'); 
      return { 
       someBold: editor.querySelector('strong').innerHTML, 
       someItalic: editor.querySelector('em').innerHTML, 
       someUnderlined: editor.querySelector('u').innerHTML, 
       someRows: editor.querySelectorAll('table tr').length, 
       someColumns: editor.querySelectorAll('table tr:first-child td').length, 
      } 
     }).end(); 
    expect(res.someBold).toEqual('Col1 Row 1'); 
    expect(res.someItalic).toEqual('Col2 Row 2'); 
    expect(res.someUnderlined).toEqual('Col3 Row 3'); 
    expect(res.someRows).toEqual(3); 
    expect(res.someColumns).toEqual(3); 
});