public void TestActionWhenContextIsATableProcessesActions()
        {
            var action = new Mock<IAction>(MockBehavior.Strict);
            var items = new List<IValidationComparer> { new StartsWithComparer() }.AsReadOnly();

            var actionRepository = new Mock<IActionRepository>(MockBehavior.Strict);
            actionRepository.Setup(a => a.GetComparisonTypes()).Returns(items);

            var tokenManager = new Mock<ITokenManager>(MockBehavior.Strict);
            tokenManager.Setup(t => t.GetToken("foo")).Returns("foo");

            var preAction = new ValidationTablePreAction(actionRepository.Object, tokenManager.Object);

            var table = new ValidationTable();
            table.AddValidation("My Field", "starts with", "foo");

            var context = new TableContext(table);
            preAction.PerformPreAction(action.Object, context);

            var validation = table.Validations.First();
            Assert.AreEqual("myfield", validation.FieldName);
            Assert.AreEqual("foo", validation.ComparisonValue);
            Assert.IsNotNull(validation.Comparer);
            Assert.IsInstanceOfType(validation.Comparer, typeof(StartsWithComparer));

            action.VerifyAll();
            actionRepository.VerifyAll();
            tokenManager.VerifyAll();
        }
        public void TestExecuteWhenFieldDoesNotExistReturnsFailure()
        {
            IPropertyData propertyData;
            var locator = new Mock<IElementLocator>(MockBehavior.Strict);
            locator.Setup(p => p.TryGetProperty("doesnotexist", out propertyData)).Returns(false);

            var validateItemAction = new ValidateItemAction
                                        {
                                            ElementLocator = locator.Object
                                        };

            var table = new ValidationTable();
            table.AddValidation("doesnotexist", "My Data", "equals");
            table.Process();

            var context = new ValidateItemAction.ValidateItemContext(table);

            var result = validateItemAction.Execute(context);

            Assert.AreEqual(false, result.Success);

            Assert.IsNotNull(result.Exception);
            StringAssert.Contains(result.Exception.Message, "doesnotexist");

            locator.VerifyAll();
        }
        public void TestExecuteWhenFieldExistsAndIsValidReturnsSuccess()
        {
            var table = new ValidationTable();
            table.AddValidation("name", "My Data", "equals");
            table.Process();

            var propData = new Mock<IPropertyData>(MockBehavior.Strict);
            string actualValue;
            propData.Setup(p => p.ValidateItem(table.Validations.First(), out actualValue)).Returns(true);

            // ReSharper disable once RedundantAssignment
            var propertyData = propData.Object;
            var locator = new Mock<IElementLocator>(MockBehavior.Strict);
            locator.Setup(p => p.TryGetProperty("name", out propertyData)).Returns(true);

            var validateItemAction = new ValidateItemAction
            {
                ElementLocator = locator.Object
            };

            var context = new ValidateItemAction.ValidateItemContext(table);

            var result = validateItemAction.Execute(context);

            Assert.AreEqual(true, result.Success);

            locator.VerifyAll();
        }
        public void TestExecuteWhenFieldDoesNotExistAndIsDoesNotExistComparerReturnsSuccess()
        {
            IPropertyData propertyData;
            var locator = new Mock<IElementLocator>(MockBehavior.Strict);
            locator.Setup(p => p.TryGetProperty("pdoesnotexist", out propertyData)).Returns(false);

            var validateItemAction = new ValidateItemAction
            {
                ElementLocator = locator.Object
            };

            var table = new ValidationTable();
            table.AddValidation("pdoesnotexist", "My Data", "doesnotexist");
            table.Process(new DoesNotExistComparer());

            var context = new ValidateItemAction.ValidateItemContext(table);

            var result = validateItemAction.Execute(context);

            Assert.AreEqual(true, result.Success);

            locator.VerifyAll();
        }
        /// <summary>
        /// Converts the SpecFlow table to a validation table. This expects a field, rule, and value column.
        /// </summary>
        /// <param name="table">The table.</param>
        /// <returns>The created validation table.</returns>
        /// <exception cref="ElementExecuteException">A table must be specified for this step with the columns 'Field', 'Rule' and 'Value'</exception>
        public static ValidationTable ToValidationTable(this Table table)
        {
            string fieldHeader = null;
            string valueHeader = null;
            string ruleHeader = null;

            if (table != null)
            {
                fieldHeader = table.Header.FirstOrDefault(h => h.NormalizedEquals("Field"));
                valueHeader = table.Header.FirstOrDefault(h => h.NormalizedEquals("Value"));
                ruleHeader = table.Header.FirstOrDefault(h => h.NormalizedEquals("Rule"));
            }

            if (fieldHeader == null || valueHeader == null || ruleHeader == null)
            {
                throw new ElementExecuteException("A table must be specified for this step with the columns 'Field', 'Rule' and 'Value'");
            }

            if (table.RowCount == 0)
            {
                throw new ElementExecuteException("The validation table must contain at least one validation row.");
            }

            var validationTable = new ValidationTable();

            foreach (var tableRow in table.Rows)
			{
				var fieldName = tableRow[fieldHeader];
				var comparisonValue = tableRow[valueHeader];
				var ruleValue = tableRow[ruleHeader];

                validationTable.AddValidation(fieldName, ruleValue, comparisonValue);
			}

            return validationTable;
        }
        public void TestExecuteWhenPropertyValidationReturnsErrorsReturnsFailureResult()
        {
            var table = new ValidationTable();
            table.AddValidation("name", "Hello", "equals");
            
            var itemResult = new ValidationItemResult();
            itemResult.NoteValidationResult(table.Validations.First(), false, "World");

            var validationResult = new ValidationResult(table.Validations) { IsValid = false, ItemCount = 1 };
            validationResult.CheckedItems.Add(itemResult);

            var propData = new Mock<IPropertyData>(MockBehavior.Strict);
            propData.SetupGet(p => p.IsList).Returns(true);
            propData.SetupGet(p => p.Name).Returns("MyProperty");
            propData.Setup(p => p.FindItemInList(It.IsAny<ICollection<ItemValidation>>()))
                    .Returns(new Tuple<IPage, ValidationResult>(null, validationResult));

            var locator = new Mock<IElementLocator>(MockBehavior.Strict);
            locator.Setup(p => p.GetProperty("myproperty")).Returns(propData.Object);

            var buttonClickAction = new GetListItemByCriteriaAction
            {
                ElementLocator = locator.Object
            };

            var context = new GetListItemByCriteriaAction.ListItemByCriteriaContext("myproperty", table);
            var result = buttonClickAction.Execute(context);

            Assert.AreEqual(false, result.Success);
            Assert.IsNotNull(result.Exception);

            locator.VerifyAll();
            propData.VerifyAll();
        }
        public void TestExecuteWhenPropertyContainsMatchingItemReturnsSuccessful()
        {
            var table = new ValidationTable();
            table.AddValidation("name", "Hello", "equals");

            var page = new Mock<IPage>();

            var propData = new Mock<IPropertyData>(MockBehavior.Strict);
            propData.SetupGet(p => p.IsList).Returns(true);
            propData.Setup(p => p.FindItemInList(It.IsAny<ICollection<ItemValidation>>()))
                    .Returns(new Tuple<IPage, ValidationResult>(page.Object, null));

            var locator = new Mock<IElementLocator>(MockBehavior.Strict);
            locator.Setup(p => p.GetProperty("myproperty")).Returns(propData.Object);

            var buttonClickAction = new GetListItemByCriteriaAction
            {
                ElementLocator = locator.Object
            };

            var context = new GetListItemByCriteriaAction.ListItemByCriteriaContext("myproperty", table);
            var result = buttonClickAction.Execute(context);

            Assert.AreEqual(true, result.Success);
            Assert.AreSame(page.Object, result.Result);

            locator.VerifyAll();
            propData.VerifyAll();
        }
        public void TestExecuteWhenPropertyValidationReturnsSuccessReturnsASuccess()
        {
            var table = new ValidationTable();
            table.AddValidation("name", "Hello", "equals");
            table.Process();

            var itemResult = new ValidationItemResult();
            itemResult.NoteValidationResult(table.Validations.First(), true, "World");

            var validationResult = new ValidationResult(table.Validations) { IsValid = true, ItemCount = 1 };
            validationResult.CheckedItems.Add(itemResult);

            var propData = new Mock<IPropertyData>(MockBehavior.Strict);
            propData.SetupGet(p => p.IsList).Returns(true);
            propData.Setup(p => p.ValidateList(ComparisonType.Equals, It.Is<ICollection<ItemValidation>>(c => c.Count == 1))).Returns(validationResult);

            var locator = new Mock<IElementLocator>(MockBehavior.Strict);
            locator.Setup(p => p.GetProperty("myproperty")).Returns(propData.Object);

            var buttonClickAction = new ValidateListAction
            {
                ElementLocator = locator.Object
            };

            var context = new ValidateListAction.ValidateListContext("myproperty", ComparisonType.Equals, table);
            var result = buttonClickAction.Execute(context);

            Assert.AreEqual(true, result.Success);

            locator.VerifyAll();
            propData.VerifyAll();
        }
		public void TestRetryValidationUntilTimeoutWithNoSuccessBeforeTimeout()
		{
			try
			{
				ValidateItemAction.RetryValidationUntilTimeout = true;
				ActionBase.DefaultTimeout = System.TimeSpan.FromMilliseconds(300); // NOTE: interval between checks is 200ms

				var table = new ValidationTable();
				table.AddValidation("name", "My Data", "equals");
				table.Process();

				var propData = new Mock<IPropertyData>(MockBehavior.Strict);
				string actualValue;
				propData.SetupSequence(p => p.ValidateItem(table.Validations.First(), out actualValue))
					.Returns(false)
					.Returns(false) // after 200ms
					.Returns(true); // after 400ms -- too late

				var propertyData = propData.Object;
				var locator = new Mock<IElementLocator>(MockBehavior.Strict);
				locator.Setup(p => p.TryGetProperty("name", out propertyData)).Returns(true);

				var validateItemAction = new ValidateItemAction
				{
					ElementLocator = locator.Object
				};

				var context = new ValidateItemAction.ValidateItemContext(table);

				var result = validateItemAction.Execute(context);

				Assert.IsFalse(result.Success);

				locator.VerifyAll();
			}
			finally
			{
				ValidateItemAction.RetryValidationUntilTimeout = false;
				ActionBase.DefaultTimeout = System.TimeSpan.FromSeconds(5);
			}
		}