2017-03-08 53 views
0

我已經開始嘗試使用Nightmare和mocha執行自動化測試。儘管遵循錯誤本身的指示,但我仍在獲取下面的錯誤。噩夢:錯誤:超過2000ms的超時。異步測試和掛鉤

var Nightmare = require('nightmare'); 
var expect = require('chai').expect; 

var url = 'http://www.google.com/' 

describe('Page availability', function() { 
    it('Should open homepage', function(done) { 
    var nightmare = Nightmare(); 

    nightmare 
     .goto(url) 
     .wait('body') 
     .evaluate(function() { 
     return document.querySelector('.gb_P').innerHTML 
     }) 
     .end() 
     .then(function(text) { 
     expect(text).to.equal('images'); 
     done(); 
     }) 
    }); 
}); 
運行與'摩卡test.js'上述腳本時

,這是輸出,我得到:

Page availability 
    1) Should open homepage 


    0 passing (2s) 
    1 failing 

    1) Page availability Should open homepage: 
    Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves. 

自白:我(還)沒有精通與承諾,但我不明白爲什麼摩卡沒有考慮到完成回調,我已經在那裏提供。

+1

哦,當我在閱讀問題概述中的標題時,我以爲你有一個_nightmare_ ...但它只是一個圖書館。 – KarelG

+0

你找到了解決方案嗎? – user3142695

回答

0

這是因爲Mocha的默認超時時間爲2秒,您的夢魘行爲可能需要比完成更長的時間。 (谷歌需要長期臭名昭著完成加載。)

裏面的describeit的,你可以設置this.timeout(ms),或運行摩卡命令時使用--timeout [ms]

0

我一直在努力與這個完全相同的問題幾個小時,終於找到了一個解決方案!

首先@Ross是正確的這裏,雖然2秒可以是不夠的,它並不總是有足夠的時間等待谷歌,或與此有關的任何其他頁面。出於這個原因,我把我的超時時間提高到了15000ms,一個安全的賭注,也許是殺人,但除非你有一個非常緩慢的互聯網連接,否則你會安全的。

其次,我發現

querySelector(selector).innerHTML 

經常返回null。這可能是由於在編寫選擇器路徑時存在大量的人爲錯誤,或者使用javascript或惡夢的.evaluate()函數在幕後發生的其他技術問題。

值得一提的是,這個問題似乎並沒有從wait()功能發起,因爲我已經發現,該框架是使用相同的查詢選擇,但調換innerHTML屬性爲length財產完全滿意。

實施例:

這將導致超時錯誤,除了.evaluate()返回null:

.wait("body > div.wrap > h1") 
    .evaluate(() => { 
     return document.querySelectorAll("body > div.wrap > h1").innerHTML; 
    }) 

而改變innerHTML來長度將通過完全正常

.wait("body > div.wrap > h1") 
    .evaluate(() => { 
     return document.querySelectorAll("body > div.wrap > h1").length; 
    }) 

我然而,這並不是爲什麼這是我的發現。

正是如此,爲了解決我用document.getElementsByClassName() OP的問題,它已被證明對我更容易和/或準確的方法獲取DOM元素

重寫OP的代碼,例如:

var Nightmare = require('nightmare'); 
var expect = require('chai').expect; 

var url = 'http://www.google.com/' 

describe('Page availability', function() { 
    this.timeout(15000); 
    it('Should open homepage', function(done) { 
     var nightmare = Nightmare(); 

     nightmare 
     .goto(url) 
     .wait('body') 
     .evaluate(function() { 
      var headerDiv = document.getElementsByClassName("gb_P"); 
      return headerDiv[1].innerHTML 
     }) 
     .end() 
     .then(function(text) { 
      expect(text).to.equal('Images'); 
      done(); 
     }) 
    }); 
}); 

產生合格測試。此外,OP已經忘記將這個類的innerHTML中的'Images'大寫。

總之

我不是querySelector(selector).innerHTML仍然可以正常工作,但是,對於針對特定類和id的getElementById()是更安全的選擇。它們也可以協同工作,例如下面的代碼對我來說運行時沒有錯誤,因爲在querySelector(selector).innerHTML中干擾整個查詢選擇器會使測試崩潰。

.wait("body > div#wpwrap > div#wpcontent > div#wpbody > div#wpbody-content > div.wrap > h1") 
    .evaluate(() => { 
     var headerDiv = document.getElementById("wpbody-content"); 
     h1Html = headerDiv.querySelector(".wrap h1").innerHTML; 
     return h1Html; 
    })