2014-11-17 20 views
9

Tôi đang cố gắng mô phỏng một phím bấm trong Jasmine (trình duyệt thử nghiệm là PhantomJS) để tôi có thể kiểm tra một số chức năng của tôi sử dụng các lần nhấn phím. Thật không may, tôi không thể kiểm tra nó đúng với Jasmine vì tôi gặp lỗi.Giả lập bấm phím giả trong hoa nhài

Dưới đây là đoạn code tôi đang cố gắng để kiểm tra:

function Controls() { 
    'use strict'; 
    this.codes = { 
    37: 'left', 
    39: 'right', 
    38: 'forward', 
    40: 'backward' 
    }; 
    this.states = { 
    'left': false, 
    'right': false, 
    'forward': false, 
    'backward': false 
    }; 
    document.addEventListener('keydown', function() { this.onKey.bind(this, true); }, false); 
    document.addEventListener('keyup', function() { this.onKey.bind(this, false); }, false); 
} 

Controls.prototype.onKey = function(val, e) { 
    var state = this.codes[e.keyCode]; 

    if (typeof state === 'undefined') return false; 

    this.states[state] = val; 

    // Stop the key press from repeating 
    e.preventDefault(); 
    e.stopPropagation(); 

    return true; 
}; 

controls = new Controls(); 

(Chú ý: Đoạn mã trên kết thúc tốt đẹp các chức năng trong addEventListener với các chức năng anon để Jasmine sẽ thực sự cố gắng để chạy thử nghiệm của tôi Nếu không có sự nặc danh. bọc, điều này dẫn đến lỗi khác: TypeError: 'undefined' is not a function (evaulating 'this.onKey.bind(this, true)' Giải quyết vấn đề này sẽ là tuyệt vời quá )

Và đây là nỗ lực của tôi lúc kiểm tra:.

function keyPress(key) { 
    var pressEvent = document.createEvent('KeyboardEvent'); 
    pressEvent.initKeyEvent('keydown', true, true, window, 
          false, false, false, false, 
          0, key); 
    document.dispatchEvent(pressEvent); 
} 

describe("Controls", function() { 
    var controls; 

    it("should initialize properly", function() { 
    controls = new Controls(); 
    expect(controls).not.toBe(null); 
    }); 

    it("should reflect changes in state when arrow keys are used", function() { 
    keyPress(37); 
    expect(controls.states[state]).toBe(37); 
    }); 
}); 

Điều này dẫn đến một lỗi từ Jasmine:

TypeError: 'undefined' is not a function (evaluating 'pressEvent.initKeyEvent('keydown', true, true, window, false, false, false, false, 0, key)') 

Tôi vẫn còn rất mới để Jasmine (và cho rằng vấn đề, Javascript), vì vậy bất kỳ sự giúp đỡ nói chung sẽ được đánh giá.

Trả lời

15

Có vẻ như vấn đề của bạn là cách bạn tạo sự kiện.

Mã ví dụ bên dưới cho biết cách sự kiện được tạo, kích hoạt và bị chặn.

var keyPressed = null; 

function keyPress(key) { 
    var event = document.createEvent('Event'); 
    event.keyCode = key; 
    event.initEvent('keydown'); 
    document.dispatchEvent(event); 
} 

document.addEventListener('keydown', function(e){ 
    keyPressed = e.keyCode; 
}); 

keyPress(37) 
alert(keyPressed); 

Dưới đây là một plunker quá: http://plnkr.co/edit/TxGXcT0DnPa44C0PkHkN?p=preview

+0

Bởi vì điều này giải quyết được vấn đề thực tế trong tầm tay, tôi chấp nhận câu trả lời này; cảm ơn Chris! Tuy nhiên, câu hỏi ban đầu của tôi không thực sự là điều tôi nên hỏi, vì vậy tôi sẽ cung cấp thêm chi tiết về điều này bên dưới. – emmabukacek

+2

Xin chào, Đây là bài đăng cũ nhưng có thể bạn biết rằng '' 'mã khóa''' hiện không còn được dùng nữa [xem bài viết MDN] (https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode). Vì vậy, mã nên sử dụng '' 'key''' hoặc' '' code''' và do đó hơi khác nhau. – ollie314

3

EDIT: Vấn đề này nên được giải quyết như của PhantomJS 2. Thông tin thêm trong vấn đề dưới đây.

Vì vậy, lý do

this.onKey.bind(this, true) 

được trả lại một lỗi là vì kể từ ngày của bài viết này, PhantomJS không hỗ trợ với phím tắt được nêu ra. Bạn có thể tìm thêm thông tin về điều đó ở đây:

https://github.com/ariya/phantomjs/issues/10522

và một lời giải thích dài từ ariya đây:

https://groups.google.com/forum/#!msg/phantomjs/r0hPOmnCUpc/uxusqsl2LNoJ

Một con đường xung quanh vấn đề này là tạo ra một polyfill theo đề nghị của creationix:

https://github.com/c9/smith/blob/master/tests/public/test.js#L2-L7

Cho tất cả điều này i nformation, nó nên làm cho thử nghiệm một chút quản lý hơn biết rằng tôi có thể phá vỡ các vấn đề nguyên mẫu. Cám ơn vì tất cả sự giúp đỡ!

Các vấn đề liên quan