Watin1.3 release

This 1.3 release is probably the last release in the 1.x line of releases and also the last one supporting the .Net 1.1 framework. Following releases will 'only' support .Net 2.0 and higher and will make use of the new C# 3.0 language improvements.

This release is a continuation if the 1.x releases and thus only supports Internet Explorer. In preparation of the final 2.0 release the code base already has changed quit a bit to allow for multiple browser support. This has led to re-organising classes and namespaces as wel as marking some classes, methods and properties with the Obsolete attribute. If you went (way) beyond the basic use of WatiN you might now encounter the new INativeElement, INativeBrowser and INativeElementFinder interfaces implemented by IEElement, IEBrowser and IEElementFinder. These interfaces are not final yet but they are the (internal) way to go for WatiN's multiple browser support (anybody interested in WatiN for Chrome?).

 

I also like to thank all who have contributed to this release with code and suggestions. A special thanks to Jeremy Wadsack of Seven Simple Machines. He contributed the new Find.Near() and Find.ByLabel() features.

 

Support for lambda expressions and Linq

One of the most exciting new features in this release is support for lambda expressions. If you use WatiN with Visual Studio 2008 you can now use lambda expessions as an alternative to the static ByXXX methods in the Find class. Following is a simple example:


using(IE ie = new IE("www.watin.example.net"))
{
 var button = ie.Button(b => b.Id == "someId");
}

Since this new construct allows you to access all properties and methods on an element, its possible to express your find constraint in just one lambda expression where previously you needed to write multiple lines of code (or even had to write your own constraint classes).
One tip, be aware of null values when inspecting attribute values of an element. For instance:
var button = ie.Button(b => b.Id != null && b.Id.ToLower() == "someid");

This release of WatiN also enables the use of Linq to find elements in a collection. The following example shows you how to use the Where Linq extension method to get all the disabled buttons on a page.

using(IE ie = new IE("www.watin.example.net"))
{
 var disabledButtons = ie.Buttons.Where(b => b.Enabled == false);
}

 

Breaking Change

To support element.WaitUntil(Predicate<T>) for .Net 2.0 and higher, the new classes Element<E> and ElementsContainer<E> are introduced. This is a BREAKING change cause the following syntax won't work any longer (with WatiN for .Net 2.0 and higher):

ElementsContainer div = ie.Div(findBy);

Change it to:

IElementsContainer div = ie.Div(findBy);

// or

ElementsContainer<Div> div = ie.Div(findBy);

// or for C# 3.0

var div = ie.Div(findBy);

 

New Find.By methods

All this new lambda power is nice but if you like to keep it lightweight than use the Find class. This release offers some new helper methods:

  • Find.ByClass(value):
    Finds elements with a matching value for the class attribute.
  • Find.First():
    A shortcut for Find.ByIndex(0).
  • Find.Near(text):
    Finds elements in the area near the specified text. Contributed by Jeremy Wadsack of Seven Simple Machines.
  • Find.ByLabel(text):
    Finds elements with a matching Label text. Contributed by Jeremy Wadsack of Seven Simple Machines.
  • Find.ByElement(ICompareElement):
    Find an element using your own comparer class implementing ICompareElement. Allows you to access all of the elements properties and methods.
  • Find.ByElement(Predicate):
    Same as previous but using a Predicate or lambda expression instead of an interface implementation.
  • Find.ByDefault():
    Will use the default constraint as specified by Settings.FindByDefaultFactory. See also the section about Settings in these release notes.

 

 

New filtering options on collections

All element collections now have the First() and First(BaseConstraint) methods. If you are only interested in the first item of a collection this will give better performance than getting the zero indexed item from a collection (ie.TextFields[0]). Example:

// Find a TextField with value 'some text' using the new First method
TextField first = ie.TextFields.First(Find.ByValue("some text"));
// instead of doing it the old way
TextField first = ie.TextFields.Filter(Find.ByValue("some text"))[0];

Also added a new Filter(predicate) method to all element collections. Using delegates or lamba's this allows more control over the elements that should be in the filter. Example:

var divs = ie.Divs.Filter(d => d.name.StartsWith("i"));

 

DialogHandler changes

Since many people are using the UseDialogOnce class included in the UnitTest project, it has been moved to the Core project. The class ensures that a dialog handler is removed when it gets disposed. See the examples below on how to use this class.

Two new dialog handlers have been introduced. One to handle the vbscript msgbox dialog (VbScriptMsgBoxDialogHandler). Thanks to Julian Jelfs for this contribution: public void Using_the_VbScriptMsgBoxDialogHandler()
{
 var ie = new IE("www.watin.example.net");

 var button = VbScriptMsgBoxDialogHandler.Button.Yes;
 var handler = new VbScriptMsgBoxDialogHandler(button);

 using (new UseDialogOnce(ie.DialogWatcher, handler))
 {
  // Click on button to show the dialog
  ie.Button("vbScriptMsgBox").Click();
 }
}

And one to handle the prompt dialog (PromptDialogHandler):

public void Using_the_PromptDialogHandler()
{
 var ie = new IE("www.watin.example.net");

 var text = "Hello";
 var handler = new PromptDialogHandler(text);
 using (new UseDialogOnce(ie.DialogWatcher, handler))
 {
  ie.Button("showPrompt").Click();
 }
}

Other changes to the dialog handlers:

  • FileDownloadHandler now close the progress dialog after the download has been completed.
  • FileDownloadHandler couldn't find the Save button in some enviroments, resulting in a time out. This has been resolved.
  • Fixed a potential infinit loop in the DialogWatcher class.
  • Log entries are written when a dialog doesn't become visible within the timeout period and when a dialog gets auto closed.

 

 

Changes to Table and TableRow

Fixed issue where Table.FindRow() was evaluating tablecells in a nested table. If you used this "bug" as a feature, tests might fail due to this fix. Also added new overloads FindRow(ICompare), FindRow(Predicate<string>) and FindRow(Predicate<TableCell>). Following an example on how to use the later:

ie.Table(findBy).FindRow(cell => Equals(cell.Text, "Some text"));

With the current Table.TableRows and TableRow.TableCells implementation you get a collection of all these elements, even if they are inside nested tables. In many scenarios a restriction to get only the cells directly related to a row (or only the rows directly related to a table) would make things a lot easier. A nice side effect is a bit of performance gain. To accomplish this the following properties are added:

  • TableRow.TableCellsDirectChildren
  • Table.TableRowsDirectChildren
  • TableBody.TableRowsDirectChildren
  • Table.FindRowInDirectChildren

 

 

Settings

Added new Setting.SleepTime to tweak waiting time when WatiN searches for an element. This value is used when WatiN does call Thread.Sleep during the search for an element. By reducing this time your tests will run (way) faster. I was able to lower this sleep time to 30 milliseconds without experiencing problems with a big suite of regression tests. The gain was about 5 minutes (from 30 to 25 minutes).

In previous releases ie.TextField("something") was basically a shorter notation for ie.TextField(Find.ById("something")). This release introduces the possibility to change the default (id) constraint so that ie.TextField("something") will be the shorter notation for ie.TextField(Find.ByDefault("something")).

Following is an example on how to setup WatiN so that it will always use Regex to find an element by id (especially handy when your working with ASP.Net id's).

// First create a class which implements IFindByDefaultFactory
// and creates a regex of the given string
public class FindByAspIdFactory : IFindByDefaultFactory
{
 public BaseConstaint ByDefault(string value)
  { return new Find.ById(new Regex(".*" + value + "$") }

 public BaseConstaint ByDefault(Regex value)
  { return new Find.ById(value) }
}

// Then assign FindByAspIdFactory to the setting FindByDefaultFactory
Settings.FindByDefaultFactory = new FindByAspIdFactory();

// Lets assume we are looking for an element
// with the id "container1_somemore_btn_next"
// Instead of ie.Button(new Regex(".*btn_next$")) you can now write
Button nextButton = ie.Button("btn_next");

Introduced a new (static) Settings class as replacement for IE.Settings. It is basically a wrapper around the class DefaultSettings implementing the new ISettings interface (same pattern as used for the Logger and LogWriter). If you did inherit from the old Settings class you should now inherit from DefaultSettings. It is also possible to create your own settings class (implementing ISettings) and assign an instance to the Settings.Instance property.

 

New Wait methods

WatiN is always waiting a while for a page to load or an element to appear on the page before it throws an (ElementNotFound)Exception. But there are occasions were you want to skip this build in waiting and take control if succes or failure your self. Following a list of new Wait and NoWait methods:

 

  • IE.GoToNoWait(string or Uri). Only available in WatiN for .Net 2.0 and higher. Thanks to Martin Sponholtz for his contribution.
  • IE.AttachtToIENoWait(Findby[, timeout]). Use this for attaching and closing browser windows which show for instance a PDF document.
  • IE.InternetExplorersNoWait(). Use this method if you want WatiN to skip calling the WaitForComplete method on an InternetExplorer instance before it is returned from the collection of open internet explorers.
  • IE.HtmlDialogsNoWait(). Use this method if you want WatiN to skip calling the WaitForComplete method on an Html dialog (model or modelles) before it is returned from the collection of open Html dialogs.
  • Added message to HtmlDialogNotFoundException about possible pop-up blocker being active
  • IE.WaitForComplete(timeout). Use this if you incidentally need a different timeout then specified by IE.Settings.WaitForCompleteTimeOut.
  • Document.WaitUntilContainsText(string[, timeout]) and Document.WaitUntilContainsText(regex[, timeout]), also available on the IE class (and others which inherit from Document)
  • Element.FireEventNoWait(event, eventProperties). To fire an element and proceed without waiting for the event to be completed.

 

 

Other functional changes

 

 

  • Made a change to improvement performance when searching elements by their exact id.
  • Added Uri property to Image.
  • Added params argument to Logger.LogAction(message, args). Calls String.Format internally.
  • When running the WatiN UnitTests they will run in stealth mode showing as less windows as possible during the test run.
  • Screen captures are now made with more color info per pixel.
  • Added documentation to the constraint classes and comparers.
  • IE.Back and IE.Forward don't throw COMException anymore when no (forward/backward) history is available. They will return a success boolean.
  • Jeff Brown fixed an issue where the IE.InternetExplorers property sometimes picked up Windows Explorer windows in which case a timeout exception was thrown.
  • Added url to the message of ElementNotFoundException.
  • Created a test with a "proof of concept" VisibleAttribute class work. Might be handy when testing AJAX websites (like the ASP.Net AJAX ModalPopupExtender control which is used to test with). This AttributeConstraint might move over to the Core someday.
  • Added possibility to find a Frame or IFrame by any of its (custom) attributes.
  • Added Frame.GetAttributeValue(attributename) to get any of the Frame or IFrame (custom) attributes.
  • Added possibility to find an Ancestor of an Element using a predicate or lambda expression.

 

 

Other technical changes

 

 

  • Added BaseConstraint.
  • AttributeConstraint is now a BaseConstraint.
  • Renamed NotAttributeConstraint to NotConstraint. Inherits from BaseConstraint.
  • Renamed IndexAttributeConstraint to IndexConstraint. Inherits from BaseConstraint.
  • Renamed AlwaysTrueAttributeConstraint to AlwaysTrueConstraint. Inherits from BaseConstraint.
  • StringComparer can now do case insensitive compare as well.
  • Added StringComparer.AreEqual static methods to compare culture invariant.
  • Moved constraint classes into their own namespace WatiN.Core.Constraints.
  • Added ElementConstraint.
  • Fixed bug where Constraints with state where not reset before they where reused. Added virtual method Reset to BaseConstraint which gets overridden in IndexConstraint to clear state.
  • ElementConstraint also accepts Element as a valid attributebag.
  • Cleaned up PredicateComparer and renamed it to PredicateStringComparer.
  • Made DomContainer.OnGetHtmlDocument public so DomContainer can be inherited by classes outside of the WatiN assembly.
  • Added static method ElementTag.IsAnInputElement(string tagName).
  • Element implements IAttributeBag.
  • Made DomContainer property on Document public.
  • Added strong name to the Nant build for Core and UnitTests (WatiNKey.snk is not in the repository)

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值