WatiN-Html元素及元素属性识别-扩展
注:些部分内容需要对WatiN代码结构有所了解。
上篇讲的WatiN原生的有一部分Html元素类,WatiN从2012年9月15日后就未见更新,随着Html新标签的出现就需要我们自己定义一些Html元素类来扩充。
1、 例子分析
以time标签为例,首先需要知道time标签在Html中起到的什么作用,在W3School中解释为:该元素能够以机器可读的方式对日期和时间进行编码。既然是表示时间,那么就我们写这个标签类的时候就需要获取和设置时间。
2、创建Html标签
a、创建实体类,实体类继承于ElementContainer<TElement>,并新增其两个属性。
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using WatiN.Core.Native; 6 7 namespace WatiN.Core 8 { 9 [ElementTag("time")] 10 public class Time : ElementContainer<Time> 11 { 12 public Time(DomContainer domContainer, INativeElement nativeElement) : base(domContainer, nativeElement) { } 13 public Time(DomContainer domContainer, ElementFinder finder) : base(domContainer, finder) { } 14 15 /// <summary> 16 /// 获取或设置datetime属性 17 /// </summary> 18 public virtual string DateTime 19 { 20 get { return GetAttributeValue("datetime"); } 21 set { SetAttributeValue("datetime", value); } 22 } 23 /// <summary> 24 /// 获取或设置pubdate属性 25 /// </summary> 26 public virtual string PubDate 27 { 28 get { return GetAttributeValue("pubdate"); } 29 set { SetAttributeValue("pubdate", value); } 30 } 31 } 32 }
b、创建检索类
1 namespace WatiN.Core 2 { 3 4 public class TimeCollection : BaseElementCollection<Time, TimeCollection> 5 { 6 7 public TimeCollection(DomContainer domContainer, ElementFinder finder) : base(domContainer, finder) { } 8 9 protected override TimeCollection CreateFilteredCollection(ElementFinder elementFinder) 10 { 11 return new TimeCollection(DomContainer, elementFinder); 12 } 13 } 14 }
c、修改NativeElementCollectionAdapter.cs类,此类为元素检索适配器,在其IElementsContainer Members代码块中添加Time元素的操作
1 public Time Time(string elementId) 2 { 3 return Time(Find.ByDefault(elementId)); 4 } 5 6 public Time Time(Regex elementId) 7 { 8 return Time(Find.ByDefault(elementId)); 9 } 10 11 public Time Time(Constraint findBy) 12 { 13 return new Time(domContainer, CreateElementFinder<Time>(findBy)); 14 } 15 16 public Time Time(Predicate<Time> predicate) 17 { 18 return Time(Find.ByElement(predicate)); 19 } 20 21 public TimeCollection Times 22 { 23 get { return new TimeCollection(domContainer, CreateElementFinder<Time>(null)); } 24 }
d、修改Document.cs类,此类为页面容器基类,其中IE、Browser、Frame、DomContainer都继承于它,在其中添加Time元素后其页面容器类中即可直接使用。将Time元素操作放入IElementsContainer代码块中。
1 #region 新增元素 2 #region Time 3 public virtual Time Time(string elementId) 4 { 5 return AllElements.Time(elementId); 6 } 7 8 public virtual Time Time(Regex elementId) 9 { 10 return AllElements.Time(elementId); 11 } 12 13 public virtual Time Time(Constraint findBy) 14 { 15 return AllElements.Time(findBy); 16 } 17 18 public virtual Time Ul(Predicate<Time> predicate) 19 { 20 return AllElements.Time(predicate); 21 } 22 23 public virtual TimeCollection Times 24 { 25 get { return AllElements.Times; } 26 } 27 #endregion 28 #endregion
e、修改元素容器类ElementContainer.cs,修改此类是为了可以在Div、P、Span等元素中使用。将Time元素操作放入IElementsContainer代码块中。
1 #region Time 2 public Time Time(string elementId) 3 { 4 return AllElements.Time(elementId); 5 } 6 7 public Time Time(Regex elementId) 8 { 9 return AllElements.Time(elementId); 10 } 11 12 public Time Time(Constraint findBy) 13 { 14 return AllElements.Time(findBy); 15 } 16 17 public Time Time(Predicate<Time> predicate) 18 { 19 return AllElements.Time(predicate); 20 } 21 22 public TimeCollection Times 23 { 24 get { return AllElements.Times; } 25 } 26 #endregion
3、验证
Html
1 <html> 2 <head> 3 <meta charset="utf-8"> 4 <title>WatiN测试页面</title> 5 </head> 6 <body> 7 <div id="arborday"><time datetime="2017-03-12">植树节</time></div> 8 <time datetime="2017-04-01">愚人节</time> 9 </body> 10 </html>
C#代码
1 public static string Test() 2 { 3 IE ie = IE.InternetExplorers().FirstOrDefault(p => !string.IsNullOrEmpty(p.Title) && p.Title == "WatiN测试页面"); 4 StringBuilder msg = new System.Text.StringBuilder(); 5 msg.Append("页面中的Time元素\r"); 6 foreach (var item in ie.Times) 7 { 8 msg.Append(item.Text + ":" + item.DateTime + "\r"); 9 } 10 Div dv = ie.Div(Find.ById("arborday")); 11 msg.Append("\rdiv中的Time元素\r"); 12 13 foreach (var item in dv.Times) 14 { 15 msg.Append(item.Text + ":" + item.DateTime + "\r"); 16 } 17 return msg.ToString(); 18 }
结果: