public IEnumerable<ValidationError> ValidateHtml(HtmlDocument document) { var records = new List<ValidationError>(); var nodes = document.GetNodes("//h1"); if (nodes.Count == 0) { records.Add(new ValidationError("There must be at least one H1 tag on the page")); } return records; }
public IEnumerable<ValidationError> ValidateHtml(HtmlDocument document) { var records = new List<ValidationError>(); var nodes = document.GetNodes("//fieldset[not(legend) or legend[not(text())]]"); foreach (var node in nodes) { string message = string.Format("Fieldset must have a legend: {0}", node.OuterHtml); records.Add(new ValidationError(message, node.Line, node.LinePosition)); } return records; }
public IEnumerable<ValidationError> ValidateHtml(HtmlDocument document) { var records = new List<ValidationError>(); const string formElementXPath = "//input[@type='image'][not(@alt) or @alt='']"; var imageButtonsWithoutAlt = document.GetNodes(formElementXPath); foreach (var imageButton in imageButtonsWithoutAlt) { string message = string.Format("Image input missing alt text: {0}", imageButton.OuterHtml); records.Add(new ValidationError(message, imageButton.Line, imageButton.LinePosition)); } return records; }
public IEnumerable<ValidationError> ValidateHtml(HtmlDocument document) { var records = new List<ValidationError>(); var textDefinition = new {TagName = "text", Description = "Textbox", IsInput = true}; var passwordDefinition = new {TagName = "password", Description = "Password textbox", IsInput = true}; var checkboxDefinition = new {TagName = "checkbox", Description = "Checkbox", IsInput = true}; var selectDefinition = new { TagName = "select", Description = "Select list", IsInput = false }; var textAreaDefinition = new { TagName = "textarea", Description = "Text area", IsInput = false }; var definitions = new[] {textDefinition, passwordDefinition, checkboxDefinition, selectDefinition, textAreaDefinition}; foreach (var definition in definitions) { var formElementXPath = definition.IsInput ? string.Format("//input[@type='{0}']", definition.TagName) : string.Format("//{0}", definition.TagName); var elements = document.GetNodes(formElementXPath); foreach (var element in elements) { var idAttribute = element.Attributes["id"]; HtmlNode correspondingLabel = null; if (idAttribute != null) { var elementId = idAttribute.Value; var xpath = string.Format("//label[@for='{0}']", elementId); correspondingLabel = document.GetNode(xpath); } if (correspondingLabel == null) { var message = string.Format("{0} missing corresponding label: {1}", definition.Description, element.OuterHtml); records.Add(new ValidationError(message, element.Line, element.LinePosition)); } } } return records; }
public IEnumerable<ValidationError> ValidateHtml(HtmlDocument document) { var records = new List<ValidationError>(); var existingLinks = new List<Link>(); const string formElementXPath = "//a"; var linksNodeList = document.GetNodes(formElementXPath); if (linksNodeList != null) foreach (var currentNode in linksNodeList) { var urlAttribute = currentNode.Attributes["href"]; var titleAttribute = currentNode.Attributes["title"]; var nameAttribute = currentNode.Attributes["name"]; var linkText = currentNode.InnerText; var url = urlAttribute == null ? string.Empty : urlAttribute.Value; var title = titleAttribute == null ? string.Empty : titleAttribute.Value; var name = nameAttribute == null ? string.Empty : nameAttribute.Value; var link = new Link(url, linkText, title, name); var matches = from c in existingLinks where c.Url != link.Url && c.Text == link.Text && c.Title == link.Title && c.Name == link.Name select c; if (!matches.Any()) existingLinks.Add(link); else { records.Add( new ValidationError( string.Format( "Link text does not make sense out of context,link is the same as another link on the page, but links to a different location: {0}", currentNode.OuterHtml))); } } return records; }
public IEnumerable<ValidationError> ValidateHtml(HtmlDocument document) { var records = new List<ValidationError>(); var labels = document.GetNodes("//label"); foreach (var label in labels) { var forAttribute = label.Attributes["for"]; HtmlNode relatedElement = null; if (forAttribute != null) { string labelId = forAttribute.Value; string xpath = string.Format("//input[@id='{0}']", labelId); relatedElement = document.GetNode(xpath); if (relatedElement == null) { xpath = string.Format("//select[@id='{0}']", labelId); relatedElement = document.GetNode(xpath); } if (relatedElement == null) { xpath = string.Format("//textarea[@id='{0}']", labelId); relatedElement = document.GetNode(xpath); } } if (relatedElement == null) { string message = string.Format("Label does not relate to a form control: {0}", label.OuterHtml); records.Add(new ValidationError(message)); } } return records; }
public IEnumerable<ValidationError> ValidateHtml(HtmlDocument document) { var records = new List<ValidationError>(); var nodes = document.GetNodes("//table"); if (nodes != null) foreach (var node in nodes) { var tableHeaders = node.GetNodes("tr/th"); var tableHeadersWithThead = node.GetNodes("thead/tr/th"); if (!tableHeaders.Any() && !tableHeadersWithThead.Any()) { string message = string.Format( "Layout table detected - if the table is a data table, use TH for the column or row headers. Otherwise, use CSS for layout: {0}", node.OuterHtml); records.Add(new ValidationError(message)); } } return records; }
public IEnumerable<ValidationError> ValidateHtml(HtmlDocument document) { var records = new List<ValidationError>(); var previousAltText = new List<string>(); const string formElementXPath = "//img"; var images = document.GetNodes(formElementXPath); foreach (var currentImage in images) { var altTextAttribute = currentImage.Attributes["alt"]; if (altTextAttribute != null) { if (previousAltText.Contains(altTextAttribute.Value)) { string message = string.Format("Image has duplicate alt text: {0}", currentImage.OuterHtml); records.Add(new ValidationError(message)); } previousAltText.Add(altTextAttribute.Value); } } return records; }