2017-04-24 94 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); 
});