weinre

weinre是一個用於瀏覽器的遠端除錯工具,運作方式與jsconsole相同,都是透過include一隻外部js script,來與server溝通傳遞資料。但是jsconsole只提供一些很基本功能,如果要能像chrome一樣,查看dom element、network等功能,可以使用weinre

使用時機:

使用android、ios等手持裝置的browser,或者對IE除錯的時候,都很適合。

weinre原理:

weinre基本原理是,建立一個console page,然後經由weinre server,與development page(你要除錯的page)互相傳遞資料溝通。( 溝通方式採用long polling)

時序圖如下:

 
透過node.js安裝:
sudo npm install -g weinre
操作流程:

開啟weinre server:

weinre --httpPort 8081 --boundHost localhost

打開瀏覽器輸入http://localhost:8081/

然後在你想要除錯的頁面加上以下script:

<script src="http://localhost:8081/target/target-script-min.js#anonymous"></script>

例如:

<!DOCTYPE HTML>                                                                                  
<html lang="en">                                                                                 
<head>                                                                                           
    <meta charset="UTF-8">                                                                       
    <title></title>                                                                              
    <script src="http://localhost:8081/target/target-script-min.js#anonymous"></script>       
</head>                        
<body>                                                                                           
    <div>weinre test</div>                                                                       
    <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> 
</body>                                                                                          
</html>                                                                                          

開啟http://localhost:8081/client/#anonymous,就可以開始除錯了。

javascript event偵錯-Visual Event 2

Visual Event會透過將javascript語法,注入到頁面的方式,取得每個element所綁定的事件。如果是常常include很多library時,或者寫一些比較複雜ui,可透Visual Event檢視綁定element上的event正不正確,方便除錯。

執行流程如下:

將以下script,加入到書籤的網址欄位:

javascript:(function()%20{var%20url%20=%20'//www.sprymedia.co.uk/VisualEvent/VisualEvent_Loader.js';if(%20typeof%20VisualEvent!='undefined'%20)%20{if%20(%20VisualEvent.instance%20!==%20null%20)%20{VisualEvent.close();}else%20{new%20VisualEvent();}}else%20{var%20n=document.createElement('script');n.setAttribute('language','JavaScript');n.setAttribute('src',url+'?rand='+new%20Date().getTime());document.body.appendChild(n);}})();

然後在選擇你要測試的頁面,執行剛剛加入的書籤,或將以上script貼到網址列,再按enter,就能偵測到綁定的event:

目前support的library如下:

  • DOM 0 events
  • jQuery 1.2+
  • YUI 2
  • MooTools 1.2+
  • Prototype 1.6+
  • Glow
  • ExtJS 4.0.x

注入的方式其實就是透過書籤、網址列可以執行javascript特性,當你點擊書籤時,就會執行script,將程式load當前頁面。在網址列執行script範例,如下:

//將以下程式碼貼到網址列按enter,就可以執行js語法
javascript:alert(3);

至於偵測event的實作,大致上是將每個element上的attribute掃過,還有針對不同library綁定event方式去處理,最後將ui呈現畫面上。

mobile web debug tool(jsconsole)

如果要在androidbrowser debug,最早期的方式,是使用adb logcat然後過濾掉其他訊息,只顯示browser的log,而ios上的Safari,則是可在設定,直接在mobile上觀看log(在mac上,可以使用類似chrome同樣的除錯介面)。但是這種除錯方式不易,只能單方面看到browser訊息,並沒辦法直接從pc上對瀏覽器下指令,而jsconsole剛好可以解決這個問題。

jsconsole提供了一個console page(jsconsole.com),會產出一個listen key,同時test page(開發者寫得測試頁面)也會include一隻script,在透過server讓test pageconsole page溝通。

step 1 在console page輸入以下code:

:listen

server會回傳

Creating connection...
Connected to "2A049E81-520B-4074-BB06-45BE8ADBE9E1"
<script src="http://jsconsole.com/remote.js?2A049E81-520B-4074-BB06-45BE8ADBE9E1"></script>

step 2 將回傳的script貼到test page:

<html>
  <head>
     <script src="http://jsconsole.com/remote.js?2A049E81-520B-4074-BB06-45BE8ADBE9E1"></script>
  </head>
<body>

</body>
</html>

這樣就配置完成,可以直接在console page,輸入javascript,也能同時接收test page裡的console.log。

step 3 在console page輸入:

alert("test");

就會看到在mobile上,跑出訊息視窗。技術猜測應該是使用long pollingserver push之類技術。

 

mobile chrome debug:

那如果使用chrome browser,可以直接在mobile選項,點選設定→開發人員工具→啟用usb網頁偵錯。

接著只要在終端機鍵入以下指令:

adb forward tcp:9222 localabstract:chrome_devtools_remote

然後在到pc上,打開chrome,在網址上輸入localhost:9222,就可以直接使用pc上的除錯工具了,比起jsconsle,對於開發者相對於友善多了。可以參考remote debugging

Qunit

Qunitjavascriptunit test之一,這套工具由jquery team撰寫的,使用的方式比起Jsunit,更有javascript風格。

首先要先配置html:
<html>
<head>
    <title>QUnit Test Suite</title>
    <link rel="stylesheet" href="../qunit/qunit.css" type="text/css" media="screen">
    <script type="text/javascript" src="../qunit/qunit.js"></script>
</head>
<body>
    <h1 id="qunit-header">QUnit Test Suite</h1>
    <h2 id="qunit-banner"></h2>
    <div id="qunit-testrunner-toolbar"></div>
    <h2 id="qunit-userAgent"></h2>
    <ol id="qunit-tests"></ol>
    <div id="qunit-fixture">test markup</div>
</body>
</html>

在html配置部分,id名稱必須依照官方的命名,簡單來說只需要將測試的程式,加入到head裡面即可

Qunit所提供的幾個function:
/**
* @param {String} name 單元測試的名稱
* @param {Number} expected 要比對的數量(可選)
* @param {function} test 要測試的function
* asyncTest需要在測試完後,多呼叫一個start()
* 否則將不會向下測試
*/
test(name,expected,test)
asyncTest(name,expected,test)

/**
* @param {Number} amount 要比對的數量
*/
expect(amount)

/**
* @param {String} name module的名稱
* @param {Object} lifecycle 用來配置初始化和結束執行的function(可選)
* 分別為setup和teardown
*/
module(name,lifecycle)

/**
* @param {boolean} state
* @param {String} message
*/
ok(state,message)

/**
* @param {*} actual 比對值
* @param {*} expected 期望值
* @param {String} message (可選)
* equal:actual == expected
* deepEqual:actual === expected(深度比對,會一層一層比對)
* strictEqual:actual === expected
*/
equal(actual,expected,message)
notEqual(actual,expected,message)
deepEqual(actual,expected,message)
notDeepEqual(actual,expected,message)
strictEqual(actual,expected,message)
notStrictEqual(actual,expected,message)

/**
* 繼續往下執行測試
*/
start()
/**
* @param {Number} timeout 延遲向下執行的時間(可選)
* 若無輸入參數會等待呼叫start才會向下執行測試
*/
stop(timeout)
幾個簡單範例:
/*
* 一個簡單範例
*/
test("module without setup/teardown (default)", function() {
    expect(1);
    ok(true);
});
/*
* setup將會先執行,而teardown會最後執行
*/
var state;
module("setup/teardown test", {
    setup: function() {
        state = true;
        ok(true);
    },
    teardown: function() {
        ok(true);
    }
});

test("module with setup/teardown", function() {
    expect(3);
    ok(true);
});

/**
* stop和start運用
*/
module("asyncTest");

// stop呼叫2次,start也必須呼叫兩次
// 才會向下執行下個test

test("sync", 2, function() {
    stop();
    setTimeout(function() {
        ok(true);
        start();
    }, 13);
    stop();
    setTimeout(function() {
        ok(true);
        start();
    }, 125);
});

// 必須呼叫start才會執行下個test

asyncTest("asyncTest", 2, function() {
    ok(true);
    setTimeout(function() {
        state = "done";
        ok(true);
        start();
    }, 13);
});

jsdoc toolkit使用在anonymous function寫法

tag:

@name  當無法辨識類型時,使用此tag直接定義名稱。(範例如下)

//利用字串建立一個function
eval("window.test= function() {};")

@lends 幫助function去參照其他class和object。

example:

/*

  • @name View
  • @class
  • @constructor
    /
    (function(){
    /*
  • @lends View
    */
    function View(){

    var _name;
    
    /**
    * @param {String} name
    */
    this.setName = function(name){
            _name = name;
    };
    

    }

/**

  • @param {string} str
    */
    View.prototype.show = function(str){
    alert(&quot;show:&quot;+str);
    
    }

})();

直接定義一個View,並將type設成class,再由內部的lends tag去參照之前所定義的名稱。  

下圖為產生的文件: jsDoc toolkit document

Jsdoc toolkit Introduction

jsdoc toolkit是一個能夠將javascript註解產成文件的工具。 tag的寫法和download可以參考相關資訊。 以下是一個簡單的example:

/**
* @author Sparrow
*/

/**
* @class Dog is an animal.
* @constructor
*/
function Dog(){

    var _name;

    /**
    * @description Set the dog name.
    * @param {string} name
    */
    this.setName = function(name){
        _name = name;
    }

    /**
    * @description Get the dog name.
    * @type String
    */
    this.getName = function(){
        return _name;
    }

}

/**
* @description Attack a target.
* @param {String} target
*/
Dog.prototype.attack = function(target){
    alert("attack:"+target);
}

最後只要在terminal執行以下指令: java -jar jsrun.jar app/run.js Dog.js -t=templates/jsdoc/