2013-10-05 14 views
6

Chúng tôi hiện đang xây dựng một ứng dụng trường xanh trong C#. Chúng tôi có các bài kiểm tra giao diện người dùng rộng rãi sử dụng Trình điều khiển web Selenium. Các bài kiểm tra này (cũng như các bài kiểm tra đơn vị) được điều hành bởi máy chủ CI của chúng tôi.Xác thực HTML5 trong C#

Selen hiển thị thuộc tính .PageSource và điều đó có ý nghĩa (đối với tôi) để chạy nguồn đó thông qua trình xác thực HTML5 như một phần khác trong mỗi thử nghiệm giao diện người dùng.

Tôi muốn nhận các loại nội dung tương tự mà http://validator.w3.org/ được chọn. Là một phần thưởng, tôi cũng muốn nhận một số vấn đề 508.

Vấn đề của tôi là tôi không thể tìm thấy bất cứ điều gì sẽ làm điều này cục bộ và dễ dàng tích hợp vào các bài kiểm tra giao diện người dùng của tôi .. Trang web W3C hiển thị api SOAP, tuy nhiên tôi không muốn truy cập trang web của họ như một phần của quá trình CI. Chúng cũng không hỗ trợ nhận phản hồi SOAP. Tôi muốn tránh cài đặt một máy chủ W3C đầy đủ tại địa phương.

Điều gần nhất mà tôi thấy là http://www.totalvalidator.com/, sử dụng nó sẽ yêu cầu viết tệp tạm thời và phân tích cú pháp báo cáo.

Tôi nghĩ tôi sẽ xem liệu có ai biết cách khác trước khi tôi đi xuống tuyến đường này không. Tốt hơn là một hội nghị DotNet mà tôi có thể gọi.

c

+0

Dịch vụ W3 là mã nguồn mở: http://validator.w3.org/source/ – Arran

Trả lời

1

Sau khi dành toàn bộ một ngày cuối tuần về vấn đề này, giải pháp duy nhất tôi có thể nhìn thấy là một thư viện thương mại gọi là CSE HTML Validator

nó nằm ở đây http://www.htmlvalidator.com/htmldownload.html

tôi đã viết một wrapper đơn giản cho nó. Đây là mã

using Newtonsoft.Json; 
using System; 
using System.Collections.Generic; 
using System.Diagnostics; 
using System.IO; 
using System.Linq; 

[assembly: CLSCompliant(true)] 
namespace HtmlValidator 
{ 

public class Validator 
{ 
    #region Constructors... 

    public Validator(string htmlToValidate) 
    { 
     HtmlToValidate = htmlToValidate; 
     HasExecuted = false; 
     Errors = new List<ValidationResult>(); 
     Warnings = new List<ValidationResult>(); 
     OtherMessages = new List<ValidationResult>(); 

    } 

    #endregion 



    #region Properties... 
    public IList<ValidationResult> Errors { get; private set; } 
    public bool HasExecuted { get; private set; } 
    public string HtmlToValidate { get; private set; } 
    public IList<ValidationResult> OtherMessages { get; private set; } 
    public string ResultsString { get; private set; } 
    public string TempFilePath { get; private set; } 
    public IList<ValidationResult> Warnings { get; private set; } 
    #endregion 



    #region Public methods... 
    public void ValidateHtmlFile() 
    { 

     WriteTempFile(); 

     ExecuteValidator(); 

     DeleteTempFile(); 

     ParseResults(); 

     HasExecuted = true; 
    } 

    #endregion 



    #region Private methods... 
    private void DeleteTempFile() 
    { 
     TempFilePath = Path.GetTempFileName(); 
     File.Delete(TempFilePath); 
    } 


    private void ExecuteValidator() 
    { 
     var psi = new ProcessStartInfo(GetHTMLValidatorPath()) 
     { 
      RedirectStandardInput = false, 
      RedirectStandardOutput = true, 
      RedirectStandardError = false, 
      UseShellExecute = false, 
      Arguments = String.Format(@"-e,(stdout),0,16 ""{0}""", TempFilePath) 
     }; 

     var p = new Process 
     { 
      StartInfo = psi 
     }; 
     p.Start(); 

     var stdOut = p.StandardOutput; 

     ResultsString = stdOut.ReadToEnd(); 
    } 


    private static string GetHTMLValidatorPath() 
    { 
     return @"C:\Program Files (x86)\HTMLValidator120\cmdlineprocessor.exe"; 
    } 


    private void ParseResults() 
    { 
     var results = JsonConvert.DeserializeObject<dynamic>(ResultsString); 
     IList<InternalValidationResult> messages = results.messages.ToObject<List<InternalValidationResult>>(); 


     foreach (InternalValidationResult internalValidationResult in messages) 
     { 
      ValidationResult result = new ValidationResult() 
      { 
       Message = internalValidationResult.message, 
       LineNumber = internalValidationResult.linenumber, 
       MessageCategory = internalValidationResult.messagecategory, 
       MessageType = internalValidationResult.messagetype, 
       CharLocation = internalValidationResult.charlocation 
      }; 

      switch (internalValidationResult.messagetype) 
      { 
       case "ERROR": 
        Errors.Add(result); 
        break; 

       case "WARNING": 
        Warnings.Add(result); 
        break; 

       default: 
        OtherMessages.Add(result); 
        break; 
      } 
     } 
    } 


    private void WriteTempFile() 
    { 
     TempFilePath = Path.GetTempFileName(); 
     StreamWriter streamWriter = File.AppendText(TempFilePath); 
     streamWriter.WriteLine(HtmlToValidate); 
     streamWriter.Flush(); 
     streamWriter.Close(); 
    } 
    #endregion 
} 
} 




public class ValidationResult 
{ 
    public string MessageType { get; set; } 
    public string MessageCategory { get; set; } 
    public string Message { get; set; } 
    public int LineNumber { get; set; } 
    public int CharLocation { get; set; } 


    public override string ToString() 
    { 
     return String.Format("{0} Line {1} Char {2}:: {3}", this.MessageType, this.LineNumber, this.CharLocation, this.Message); 

    } 

} 


public class InternalValidationResult 
{ 
    /* 
    * DA: this class is used as in intermediate store of messages that come back from the underlying validator. The fields must be cased as per the underlying Json object. 
    * That is why they are ignored. 
    */ 
    #region Properties... 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "charlocation"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "charlocation")] 
    public int charlocation { get; set; } 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "linenumber"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "linenumber")] 

    public int linenumber { get; set; } 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "message"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "message")] 

    public string message { get; set; } 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "messagecategory"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "messagecategory")] 
    public string messagecategory { get; set; } 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "messagetype"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "messagetype")] 

    public string messagetype { get; set; } 
    #endregion 
} 

CÁCH DÙNG/Testing

private const string ValidHtml = "<!DOCType html><html><head></head><body><p>Hello World</p></body></html>"; 
    private const string BrokenHtml = "<!DOCType html><html><head></head><body><p>Hello World</p></body>"; 

    [TestMethod] 
    public void CanValidHtmlStringReturnNoErrors() 
    { 
     Validator subject = new Validator(ValidHtml); 
     subject.ValidateHtmlFile(); 
     Assert.IsTrue(subject.HasExecuted); 
     Assert.IsTrue(subject.Errors.Count == 0); 
    } 


    [TestMethod] 
    public void CanInvalidHtmlStringReturnErrors() 
    { 
     Validator subject = new Validator(BrokenHtml); 
     subject.ValidateHtmlFile(); 
     Assert.IsTrue(subject.HasExecuted); 
     Assert.IsTrue(subject.Errors.Count > 0); 
     Assert.IsTrue(subject.Errors[0].ToString().Contains("ERROR")); 
    } 
0

Dường như liên kết này có thể có những gì bạn muốn: Automated W3C Validation

Bạn có thể tải về một validator đánh dấu câu trả lời chấp nhận và vượt qua HTML của bạn vào đó. Xin lỗi họ không phải là hội đồng .NET: /, nhưng bạn có thể bọc nó trong một DLL nếu bạn thực sự muốn.

Ngoài ra, một trong những câu trả lời về câu hỏi này gợi ý rằng dịch vụ W3C thực sự cho thấy một API RESTful, nhưng có thể trở lại một phản ứng SOAP: How might I use the W3C Markup Validator API in my .NET application?

+0

Cảm ơn trả lời của bạn. Không có công cụ nhị phân nào trong liên kết đầu tiên có thể xử lý HTML5. Dịch vụ W3C dường như không cho phép bạn kết hợp các phản hồi SOAP với việc gửi nội dung tùy ý để được xác thực (nghĩa là bạn chỉ có thể cung cấp cho họ liên kết đến các trang web để kiểm tra). Http://www.htmlvalidator.com/htmlval/developer.html này dường như là giải pháp tốt nhất từ ​​trước tới nay. Đó là dòng lệnh điều khiển và có thể xử lý HTML5. – Dave

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