Index: trunk/src/Core/ElementFactory.cs =================================================================== --- trunk/src/Core/ElementFactory.cs (revision 1167) +++ trunk/src/Core/ElementFactory.cs (working copy) @@ -176,12 +176,22 @@ { if (elementTypeByTag.ContainsKey(tag)) { - throw new InvalidOperationException( - string.Format("Types {0} and {1} have both registered element tag '{2}'.", - elementTypeByTag[tag], elementType, tag)); + var existingElement = elementTypeByTag[tag]; + if (elementType.IsSubclassOf(existingElement)) + { + elementTypeByTag[tag] = elementType; + } + else + { + throw new InvalidOperationException( + string.Format("Types {0} and {1} have both registered element tag '{2}'.", + existingElement, elementType, tag)); + } } - - elementTypeByTag.Add(tag, elementType); + else + { + elementTypeByTag.Add(tag, elementType); + } } return true; Index: trunk/src/UnitTests/ElementFactoryTests.cs =================================================================== --- trunk/src/UnitTests/ElementFactoryTests.cs (revision 1167) +++ trunk/src/UnitTests/ElementFactoryTests.cs (working copy) @@ -16,8 +16,11 @@ #endregion Copyright +using System; +using System.Collections; using NUnit.Framework; using NUnit.Framework.SyntaxHelpers; +using WatiN.Core.Native; namespace WatiN.Core.UnitTests { @@ -102,6 +105,51 @@ Assert.That(elementTags[0].IsAny, Is.True, "Unexpected number of element tagnames"); } + [Test] + public void Test_register_same_tag_but_inherited() + { + // GIVEN + var typeToRegister = typeof(TestElementSameTagButInherited); + var existingTags = ElementFactory.GetElementTags(typeof(Link)); + + // WHEN + ElementFactory.RegisterElementType(typeToRegister); + + // THEN + var tags = ElementFactory.GetElementTags(typeToRegister); + Assert.AreEqual(existingTags.Count, tags.Count); + foreach (var tag in existingTags) + { + Assert.Contains(tag, (ICollection)tags); + } + } + + [Test] + public void Test_register_same_tag_but_not_inherited() + { + // GIVEN + var typeToRegister = typeof(TestElementSameTagButNotInherited); + + // WHEN + try + { + ElementFactory.RegisterElementType(typeToRegister); + Assert.Fail( + "This should has been throw exception {0}", + typeof(InvalidOperationException).Name); + } + + // THEN + catch (InvalidOperationException e) + { + // don't get the first part of the message becasue we don't + // know the existing registered element. + string message = e.Message.Substring(e.Message.IndexOf(" and ")); + Assert.AreEqual(" and WatiN.Core.UnitTests.TestElementSameTagButNotInherited " + + "have both registered element tag 'A'.", + message); + } + } } public class TestElementWithNoElementTags : TestElement @@ -113,6 +161,34 @@ { } + [ElementTag("a")] + public class TestElementSameTagButNotInherited : Element + { + public TestElementSameTagButNotInherited(DomContainer domContainer, INativeElement element) + : base(domContainer, element) + { + } + + public TestElementSameTagButNotInherited(DomContainer domContainer, ElementFinder finder) + : base(domContainer, finder) + { + } + } + + [ElementTag("a")] + public class TestElementSameTagButInherited : Link + { + public TestElementSameTagButInherited(DomContainer domContainer, INativeElement element) + : base(domContainer, element) + { + } + + public TestElementSameTagButInherited(DomContainer domContainer, ElementFinder finder) + : base(domContainer, finder) + { + } + } + [ElementTag("div", Index = 0)] [ElementTag("span", Index = 1)] public class TestElement