2015-04-23 19 views
5

Tôi có chỉ thị tùy chỉnh hiển thị/ẩn phần tử dựa trên giá trị của một dịch vụ khác. Tôi đã thử tạo một bài kiểm tra để xem liệu chỉ thị có làm được gì không. Lúc đầu, tôi đã kiểm tra lại bộ chọn ": có thể nhìn thấy", nhưng nó luôn luôn trả về false ngay cả khi tôi biết rằng phần tử đã thực sự hiển thị.Kiểm tra nếu chỉ thị góc tùy chỉnh hiển thị/ẩn phần tử

it('Should show element if logged', function() { 
    element = angular.element('<p hc-auth>Some Text</p>'); 
    AuthService.Logged = true; 
    scope = $rootScope.$new(); 
    scope.$apply(function() { 
     $compile(element)(scope); 
    }); 
    expect(element.is(":visible")).toBeTruthy(); 
}); 

Sau khi một số lỗi, tôi nhận ra rằng trong quá trình thực thi, các phần tử có chiều rộng và chiều cao từ 0 ngay cả khi màn hình đã được thiết lập để ngăn chặn, và do đó ": nhìn thấy được" chọn luôn trả về false. Tôi đã thay đổi nó để kiểm tra bộ chọn hiển thị thay vào đó và bây giờ nó kiểm tra chính xác phần tử, nhưng điều này dường như quá phụ thuộc vào việc thực hiện cách hiển thị một phần tử.

it('Should show element if logged', function() { 
    element = angular.element('<p hc-auth>Some Text</p>'); 
    AuthService.Logged = true; 
    scope = $rootScope.$new(); 
    scope.$apply(function() { 
     $compile(element)(scope); 
    }); 
    expect(element.css('display')).toBe('block'); 
}); 

Cách tiếp cận tốt nhất cho tình huống này là gì?

Trả lời

6

Câu hỏi của bạn đã cho tôi hỏi làm thế nào kiểm tra ngHidengShow góc, đây là một đoạn trích từ tập tin đặc điểm của chúng:

it('should show if the expression is a function with a no arguments', function() { 
    element = jqLite('<div ng-show="exp"></div>'); 
    element = $compile(element)($scope); 
    $scope.exp = function() {}; 
    $scope.$digest(); 
    expect(element).toBeShown(); 
}); 

vẻ gọn gàng. Lúc đầu, tôi nghĩ rằng họ phải sử dụng jquery-jasmine mà không vạch trần một khớp toBeHidden (mặc dù không toBeShown khi nó quay ra), trên thực tế họ đã viết riêng custom matcher của họ để xác định tầm nhìn:

// [jtrussell] Custom Jasmine Matcher 
toBeShown: function() { 
    this.message = valueFn(
     "Expected element " + (this.isNot ? "" : "not ") + "to have 'ng-hide' class"); 
    return !isNgElementHidden(this.actual); 
} 

// [jtrussell] ... 

// [jtrussell] The helper from elsewhere in same file 
function isNgElementHidden(element) { 
    // we need to check element.getAttribute for SVG nodes 
    var hidden = true; 
    forEach(angular.element(element), function(element) { 
    if ((' ' + (element.getAttribute('class') || '') + ' ').indexOf(' ng-hide ') === -1) { 
     hidden = false; 
    } 
    }); 
    return hidden; 
} 

Vì vậy, tôi đoán họ đang gian lận một chút ... kiểm tra sự tồn tại của một lớp học .ng-hide để xác định khả năng hiển thị. Nhưng tôi cho rằng họ đã từng ở trong giày của bạn và quyết định đây là tuyến đường tốt nhất, vì góc cạnh đó đã hỗ trợ tên lớp này.

Vì chúng tôi đã sử dụng góc cạnh nên bạn có thể cân nhắc sử dụng lớp .ng-hide để đặt chế độ hiển thị và viết một trình trợ giúp tương tự.

Edit:

Như một mặt lưu ý, tôi sẽ nói rằng việc thêm/gỡ bỏ .ng-hide để thiết lập mức hiển thị sẽ có lợi ích nhận được miễn phí bất kỳ ngAnimations người sử dụng mô-đun của bạn đã đưa ra cho rằng lớp học.

+0

Tôi muốn nói đó là cách chính xác. Vì Angular 1.2, cả hai lệnh 'ngShow' và' ngHide' đều áp dụng lớp 'ng-hide' thay vì thay đổi thuộc tính' display' thành 'none' hoặc' block'. Vì vậy, tôi nghĩ rằng nó an toàn để kiểm tra lớp đó khi kiểm tra 'ngHide' hoặc' ngShow'. –

+0

Vâng thực sự tôi đã kết thúc việc thay đổi triển khai của mình để thêm/xóa lớp ng-hide và kiểm tra nó trên bài kiểm tra giống như bạn đã nói, tôi đoán đây là cách tốt nhất để đi. cảm ơn! –

1

Vì phần tử là hiển thị là một thuật ngữ được tải và :visible không phải là bộ chọn CSS thực không có dấu đầu dòng bạc.

Dưới đây là một vài khả năng

  1. sử dụng not trong Jasmine.

    mong đợi (element.css ('display')). Not.toBe ('hidden');

Tuy nhiên, điều đó sẽ không bao gồm trường hợp phần tử được hiển thị nhưng không hiển thị vì phần tử không có độ mờ hoặc nằm phía sau phần tử khác.

  1. Lấy getBoundingClientRect() cho phần tử. Sau đó kiểm tra xem document.elementFromPoint cho mỗi góc không trả về phần tử bạn mong muốn bị ẩn.

:

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