示例#1
0
        /// <summary>
        /// Sets the value of a picklist or status field.
        /// </summary>
        /// <param name="control">The option you want to set.</param>
        /// <example>xrmApp.Entity.SetValue(new OptionSet { Name = "preferredcontactmethodcode", Value = "Email" });</example>
        public static BrowserCommandResult <bool> SetValueFix(this WebClient client, OptionSet control, ContainerType formContextType)
        {
            var controlName = control.Name;

            return(client.Execute(BrowserOptionHelper.GetOptions($"Set OptionSet Value: {controlName}"), driver =>
            {
                IWebElement fieldContainer = null;

                if (formContextType == ContainerType.Body)
                {
                    // Initialize the entity form context
                    var formContext = driver.WaitUntilAvailable(By.XPath(AppElements.Xpath[AppReference.Entity.FormContext]));
                    fieldContainer = formContext.WaitUntilAvailable(By.XPath(AppElements.Xpath[AppReference.Entity.TextFieldContainer].Replace("[NAME]", controlName)));
                }
                else if (formContextType == ContainerType.Header)
                {
                    // Initialize the Header context
                    var formContext = driver.WaitUntilAvailable(By.XPath(AppElements.Xpath[AppReference.Entity.HeaderContext]));
                    fieldContainer = formContext.WaitUntilAvailable(By.XPath(AppElements.Xpath[AppReference.Entity.TextFieldContainer].Replace("[NAME]", controlName)));
                }
                else if (formContextType == ContainerType.Dialog)
                {
                    // Initialize the Dialog context
                    var formContext = driver.WaitUntilAvailable(SeleniumFunctions.Selectors.GetXPathSeleniumSelector(SeleniumSelectorItems.Dialog_Container));
                    fieldContainer = formContext.WaitUntilAvailable(By.XPath(AppElements.Xpath[AppReference.Entity.TextFieldContainer].Replace("[NAME]", controlName)));
                }

                TrySetValue(fieldContainer, control);
                return true;
            }));
        }
 public static bool ScriptErrorExists(this WebClient client)
 {
     return(client.Execute(BrowserOptionHelper.GetOptions($"Confirm or Cancel Confirmation Dialog"), driver =>
     {
         return driver.HasElement(Selectors.GetXPathSeleniumSelector(SeleniumSelectorItems.Entity_ScriptErrorDialog));
     }));
 }
        public static void ClickSubgridButton(this WebClient client, string subgridName, string subgridButtonId)
        {
            client.Execute(BrowserOptionHelper.GetOptions($"Set Value"), driver =>
            {
                var subGrid = driver.WaitUntilAvailable(Selectors.GetXPathSeleniumSelector(SeleniumSelectorItems.Entity_SubGrid, subgridName), $"Unable to find subgrid: {subgridName}");

                var menuBar = subGrid.FindElement(Selectors.GetXPathSeleniumSelector(SeleniumSelectorItems.Entity_SubGrid_ButtonList));

                var buttons = menuBar.FindElements(By.TagName("button"));

                var button = buttons.FirstOrDefault(b => b.GetAttribute("data-id").Contains(subgridButtonId));
                if (button != null)
                {
                    button.Click();
                    return(true);
                }

                var moreCommands = buttons.FirstOrDefault(b => b.GetAttribute("data-id").Equals("OverflowButton"));
                if (moreCommands == null)
                {
                    throw new TestExecutionException(Constants.ErrorCodes.MORE_COMMANDS_NOT_FOUND);
                }
                moreCommands.Click();

                var flyout = driver.FindElement(Selectors.GetXPathSeleniumSelector(SeleniumSelectorItems.FlyoutRoot));
                flyout.FindElement(Selectors.GetXPathSeleniumSelector(SeleniumSelectorItems.Entity_SubGrid_Button, subgridButtonId)).Click();

                return(true);
            });
        }
 public static string GetErrorDialogMessage(this WebClient client)
 {
     return(client.Execute(BrowserOptionHelper.GetOptions($"Get error dialog message"), driver =>
     {
         return GetErrorDialogMessage(driver);
     }).Value);
 }
示例#5
0
        public RequiredState GetRequiredState()
        {
            BrowserCommandResult <RequiredState> result = App.Client.Execute(BrowserOptionHelper.GetOptions($"Check field requirement"), driver =>
            {
                IWebElement fieldContainer = driver.WaitUntilAvailable(By.XPath(AppElements.Xpath[AppReference.Entity.TextFieldContainer].Replace("[NAME]", LogicalName)));
                if (fieldContainer == null)
                {
                    throw new TestExecutionException(Constants.ErrorCodes.FIELD_NOT_ON_FORM, LogicalName);
                }

                if (fieldContainer.TryFindElement(SeleniumFunctions.Selectors.GetXPathSeleniumSelector(SeleniumSelectorItems.Entity_FormState_RequiredOrRecommended, LogicalName), out IWebElement requiredElement))
                {
                    if (requiredElement.GetAttribute("innerText") == "*")
                    {
                        return(RequiredState.Required);
                    }
                    else
                    {
                        return(RequiredState.Recommended);
                    }
                }
                else
                {
                    return(RequiredState.Optional);
                }
            });

            return(result.Value);
        }
示例#6
0
        public static void ConfirmDuplicate(this WebClient client, bool saveIfDuplicate)
        {
            client.Execute(BrowserOptionHelper.GetOptions($"Confirm or Cancel Confirmation Dialog"), driver =>
            {
                var element = driver.WaitUntilAvailable(By.XPath(AppElements.Xpath[AppReference.Entity.DuplicateDetectionIgnoreAndSaveButton]), new TimeSpan(0, 0, 5));

                if (element != null)
                {
                    if (saveIfDuplicate)
                    {
                        var duplicateDetectionGrid = driver.FindElement(Selectors.GetXPathSeleniumSelector(SeleniumSelectorItems.DuplicateDetection_Grid));
                        var selectedItems          = duplicateDetectionGrid.FindElements(Selectors.GetXPathSeleniumSelector(SeleniumSelectorItems.DuplicateDetection_SelectedItems));

                        foreach (var item in selectedItems)
                        {
                            item.Click();
                        }

                        driver.ClickWhenAvailable(By.XPath(AppElements.Xpath[AppReference.Entity.DuplicateDetectionIgnoreAndSaveButton]));
                    }
                    else
                    {
                        throw new TestExecutionException(Constants.ErrorCodes.DUPLICATE_RECORD_DETECTED);
                    }
                }

                return(true);
            });
        }
        public static IReadOnlyCollection <FormNotification> GetFormNotifications(this WebClient client)
        {
            return(client.Execute(BrowserOptionHelper.GetOptions($"Set Value"), driver =>
            {
                List <FormNotification> notifications = new List <FormNotification>();

                if (!driver.TryFindElement(Selectors.GetXPathSeleniumSelector(SeleniumSelectorItems.Entity_FormNotifcation_NotificationBar),
                                           out var notificationBar))
                {
                    return notifications;
                }

                if (notificationBar.TryFindElement(Selectors.GetXPathSeleniumSelector(SeleniumSelectorItems.Entity_FormNotifcation_ExpandButton), out var expandButton))
                {
                    if (!Convert.ToBoolean(notificationBar.GetAttribute("aria-expanded")))
                    {
                        expandButton.Click();
                    }

                    notificationBar = driver.WaitUntilAvailable(Selectors.GetXPathSeleniumSelector(SeleniumSelectorItems.FlyoutRoot), TimeSpan.FromSeconds(2), "Failed to open the form notifications");
                }

                var notificationList = notificationBar.FindElement(Selectors.GetXPathSeleniumSelector(SeleniumSelectorItems.Entity_FormNotifcation_NotificationList));
                var notificationListItems = notificationList.FindElements(By.TagName("li"));

                foreach (var item in notificationListItems)
                {
                    var icon = item.FindElement(Selectors.GetXPathSeleniumSelector(SeleniumSelectorItems.Entity_FormNotifcation_NotificationTypeIcon));

                    var notification = new FormNotification
                    {
                        Message = item.GetAttribute("aria-label")
                    };

                    if (icon.HasClass("MarkAsLost-symbol"))
                    {
                        notification.Type = FormNotificationType.Error;
                    }
                    else if (icon.HasClass("Warning-symbol"))
                    {
                        notification.Type = FormNotificationType.Warning;
                    }
                    else if (icon.HasClass("InformationIcon-symbol"))
                    {
                        notification.Type = FormNotificationType.Information;
                    }
                    else
                    {
                        throw new TestExecutionException(Constants.ErrorCodes.UNKNOWN_FORM_NOTIFICATION_TYPE, icon.GetAttribute("class"));
                    }

                    notifications.Add(notification);
                }



                return notifications;
            }).Value);
        }
示例#8
0
 private bool MustSave()
 {
     return(_app.Client.Execute(BrowserOptionHelper.GetOptions($"WaitUntilSaveCompleted"), driver =>
     {
         var saveStatus = driver.FindElement(SeleniumFunctions.Selectors.GetXPathSeleniumSelector(SeleniumSelectorItems.Entity_SaveStatus));
         return !string.IsNullOrEmpty(saveStatus.Text) && saveStatus.Text.ToLower() == "- unsaved";
     }));
 }
示例#9
0
        /// <summary>
        /// Sets the value of a Date Field.
        /// </summary>
        /// <param name="field">Date field name.</param>
        /// <param name="value">DateTime value.</param>
        /// <param name="formatDate">Datetime format matching Short Date formatting personal options.</param>
        /// <param name="formatTime">Datetime format matching Short Time formatting personal options.</param>
        /// <example>xrmApp.Entity.SetValue("birthdate", DateTime.Parse("11/1/1980"));</example>
        public static BrowserCommandResult <bool> SetValueFix(this WebClient client, string field, DateTime?value, string formatDate = null, string formatTime = null)
        {
            return(client.Execute(BrowserOptionHelper.GetOptions($"Set Date/Time Value: {field}"), driver =>
            {
                driver.WaitForTransaction();
                var xPath = By.XPath(AppElements.Xpath[AppReference.Entity.FieldControlDateTimeInputUCI].Replace("[FIELD]", field));

                var dateField = driver.WaitUntilAvailable(xPath, $"Field: {field} Does not exist");
                try
                {
                    var date = value.HasValue ? formatDate == null ? value.Value.ToShortDateString() : value.Value.ToString(formatDate) : string.Empty;
                    driver.RepeatUntil(() =>
                    {
                        ClearFieldValue(dateField, client.Browser);
                        dateField.SendKeys(date);
                    },
                                       d => dateField.GetAttribute("value") == date,
                                       new TimeSpan(0, 0, 9), 3
                                       );
                    driver.WaitForTransaction();
                }
                catch (WebDriverTimeoutException ex)
                {
                    throw new InvalidOperationException($"Timeout after 10 seconds. Expected: {value}. Actual: {dateField.GetAttribute("value")}", ex);
                }
                // Try Set Time
                var timeFieldXPath = By.XPath($"//div[contains(@data-id,'{field}.fieldControl._timecontrol-datetime-container')]/div/div/input");
                bool success = driver.TryFindElement(timeFieldXPath, out var timeField);
                if (!success || timeField == null)
                {
                    return true;
                }
                try
                {
                    var time = value.HasValue ? formatTime == null ? value.Value.ToShortTimeString() : value.Value.ToString(formatTime) : string.Empty;
                    driver.RepeatUntil(() =>
                    {
                        ClearFieldValue(timeField, client.Browser);
                        timeField.SendKeys(time + Keys.Tab);
                    },
                                       d => timeField.GetAttribute("value") == time,
                                       new TimeSpan(0, 0, 9), 3
                                       );
                    driver.WaitForTransaction();
                }
                catch (WebDriverTimeoutException ex)
                {
                    throw new InvalidOperationException($"Timeout after 10 seconds. Expected: {value}. Actual: {timeField.GetAttribute("value")}", ex);
                }

                return true;
            }));
        }
示例#10
0
        public bool IsLocked()
        {
            return(App.Client.Execute(BrowserOptionHelper.GetOptions($"Check field locked state"), driver =>
            {
                IWebElement fieldContainer = driver.WaitUntilAvailable(By.XPath(AppElements.Xpath[AppReference.Entity.TextFieldContainer].Replace("[NAME]", LogicalName)));
                if (fieldContainer == null)
                {
                    throw new TestExecutionException(Constants.ErrorCodes.FIELD_NOT_ON_FORM, LogicalName);
                }

                return fieldContainer.TryFindElement(SeleniumFunctions.Selectors.GetXPathSeleniumSelector(SeleniumSelectorItems.Entity_FormState_LockedIcon, LogicalName), out IWebElement requiredElement);
            }).Value);
        }
示例#11
0
        public EntityReference ReviseQuote()
        {
            Logger.WriteLine("Revising Quote");
            return(_app.Client.Execute(BrowserOptionHelper.GetOptions($"Revise Quote"), driver =>
            {
                ClickButton(_app.ButtonTexts.ReviseQuote);

                _app.Client.Browser.ThinkTime(1000);
                HelperMethods.WaitForFormLoad(driver);

                return new EntityReference("quote", _app.App.Entity.GetObjectId());;
            }).Value);
        }
示例#12
0
        private void CreateOrderDialog()
        {
            _app.Client.Execute(BrowserOptionHelper.GetOptions($"Create Sales Order"), driver =>
            {
                var container = driver.WaitUntilAvailable(SeleniumFunctions.Selectors.GetXPathSeleniumSelector(SeleniumSelectorItems.Dialog_Container));
                var button    = container.FindElement(SeleniumFunctions.Selectors.GetXPathSeleniumSelector(SeleniumSelectorItems.Dialog_OK));

                button.Click();
                HelperMethods.WaitForFormLoad(driver, new FormIsOfEntity("salesorder"));

                return(true);
            });
        }
        private void CreateOrderDialog()
        {
            _app.Client.Execute(BrowserOptionHelper.GetOptions($"Create Sales Order"), driver =>
            {
                var container = driver.WaitUntilAvailable(By.XPath(Constants.XPath.DIALOG_CONTAINER));
                var button    = container.FindElement(By.XPath(Constants.XPath.DIALOG_OK));

                button.Click();
                HelperMethods.WaitForFormLoad(driver, new FormIsOfEntity("salesorder"));

                return(true);
            });
        }
示例#14
0
        public FormData OpenCreatedRecord(UCIBrowser browser, string childEntityName)
        {
            _app.Client.Execute(BrowserOptionHelper.GetOptions("Open Quick Create Child"), (driver) =>
            {
                driver.WaitUntilClickable(
                    SeleniumFunctions.Selectors.GetXPathSeleniumSelector(SeleniumSelectorItems.Entity_QuickCreate_OpenChildButton),
                    TimeSpan.FromSeconds(5),
                    null,
                    () => throw new TestExecutionException(Constants.ErrorCodes.QUICK_CREATE_CHILD_NOT_AVAILABLE)).Click();

                HelperMethods.WaitForFormLoad(driver, new FormIsOfEntity(childEntityName));
                return(true);
            });
示例#15
0
        /// <summary>
        /// Sets the value of a Date Field.
        /// </summary>
        /// <param name="field">Date field name.</param>
        /// <param name="date">DateTime value.</param>
        /// <param name="format">Datetime format matching Short Date & Time formatting personal options.</param>
        /// <example>xrmApp.Entity.SetValue("birthdate", DateTime.Parse("11/1/1980"));</example>
        public static BrowserCommandResult <bool> SetValueFix(this WebClient client, string field, DateTime date, string format = "M/d/yyyy h:mm tt")
        {
            return(client.Execute(BrowserOptionHelper.GetOptions($"Set Value"), driver =>
            {
                driver.WaitForTransaction();

                var dateContainer = SeleniumFunctions.Selectors.GetXPathSeleniumSelector(SeleniumSelectorItems.Entity_DateContainer, field);
                var dateField = AppElements.Xpath[AppReference.Entity.FieldControlDateTimeInputUCI].Replace("[FIELD]", field);

                if (driver.HasElement(dateContainer))
                {
                    var container = driver.WaitUntilAvailable(dateContainer);
                    var fieldElement = container.FindElement(By.XPath("." + dateField));

                    fieldElement.SendKeys(Keys.Control + "a");
                    fieldElement.SendKeys(Keys.Backspace);

                    if (driver.TryFindElement(SeleniumFunctions.Selectors.GetXPathSeleniumSelector(SeleniumSelectorItems.Entity_DateTime_Time_Input, field), out var timeElement))
                    {
                        driver.ClearFocus();
                        driver.WaitForTransaction();
                        try
                        {
                            driver.WaitFor(d => string.IsNullOrWhiteSpace(timeElement.GetAttribute("value")) || timeElement.GetAttribute("value") == "---");
                        }
                        catch (WebDriverTimeoutException ex)
                        {
                            throw new InvalidOperationException($"Timeout after 30 seconds. Expected cleared DateTime. Actual: {fieldElement.GetAttribute("value")}", ex);
                        }
                    }

                    fieldElement.SendKeys(date.ToString(format));

                    try
                    {
                        driver.WaitFor(d => fieldElement.GetAttribute("value") == date.ToString(format));
                    }
                    catch (WebDriverTimeoutException ex)
                    {
                        throw new InvalidOperationException($"Timeout after 30 seconds. Expected: {date.ToString(format)}. Actual: {fieldElement.GetAttribute("value")}", ex);
                    }
                    driver.ClearFocus();
                }
                else
                {
                    throw new InvalidOperationException($"Field: {field} Does not exist");
                }

                return true;
            }));
        }
示例#16
0
        public bool IsButtonAvailable(string name)
        {
            return(_app.Client.Execute(BrowserOptionHelper.GetOptions($"Check ribbon button"), driver =>
            {
                IWebElement ribbon = null;

                //Find the button in the CommandBar
                if (driver.HasElement(By.XPath(AppElements.Xpath[AppReference.CommandBar.Container])))
                {
                    ribbon = driver.FindElement(By.XPath(AppElements.Xpath[AppReference.CommandBar.Container]));
                }

                if (ribbon == null)
                {
                    if (driver.HasElement(By.XPath(AppElements.Xpath[AppReference.CommandBar.ContainerGrid])))
                    {
                        ribbon = driver.FindElement(By.XPath(AppElements.Xpath[AppReference.CommandBar.ContainerGrid]));
                    }
                    else
                    {
                        throw new InvalidOperationException("Unable to find the ribbon.");
                    }
                }

                //Get the CommandBar buttons
                var items = ribbon.FindElements(By.TagName("li"));

                //Is the button in the ribbon?
                if (items.Any(x => x.GetAttribute("aria-label").Equals(name, StringComparison.OrdinalIgnoreCase)))
                {
                    return true;
                }
                else
                {
                    //Is the button in More Commands?
                    if (items.Any(x => x.GetAttribute("aria-label").Equals("More Commands", StringComparison.OrdinalIgnoreCase)))
                    {
                        //Click More Commands
                        items.FirstOrDefault(x => x.GetAttribute("aria-label").Equals("More Commands", StringComparison.OrdinalIgnoreCase)).Click(true);
                        driver.WaitForTransaction();

                        //Find the button
                        return driver.HasElement(By.XPath(AppElements.Xpath[AppReference.CommandBar.Button].Replace("[NAME]", name)));
                    }
                    else
                    {
                        return false;
                    }
                }
            }));
        }
 public static string GetErrorDialogMessage(this WebClient client)
 {
     return(client.Execute(BrowserOptionHelper.GetOptions($"Get error dialog message"), driver =>
     {
         if (driver.TryFindElement(Selectors.GetXPathSeleniumSelector(SeleniumSelectorItems.Dialog_Subtitle), out IWebElement subTitle))
         {
             return subTitle.Text;
         }
         else
         {
             return null;
         }
     }).Value);
 }
        public void FinishDialog()
        {
            _app.Client.Execute(BrowserOptionHelper.GetOptions($"Opening opportunity close dialog"), driver =>
            {
                driver.WaitUntilClickable(By.XPath(AppElements.Xpath[AppReference.Dialogs.CloseOpportunity.Ok]),
                                          new TimeSpan(0, 0, 5),
                                          d => { driver.ClickWhenAvailable(By.XPath(AppElements.Xpath[AppReference.Dialogs.CloseOpportunity.Ok])); },
                                          () => { throw new InvalidOperationException("The Close Opportunity dialog is not available."); });

                HelperMethods.WaitForFormLoad(_app.WebDriver, new NoBusinessProcessError(), new RecordHasStatus(_closeAsWon ? "Won" : "Lost"));

                return(true);
            });
        }
        private static bool OpenOpportunityCloseDialog(WebClient client, FormData formData, bool closeAsWon)
        {
            if (closeAsWon)
            {
                formData.CommandBar.ClickButton("Close as Won");
            }
            else
            {
                formData.CommandBar.ClickButton("Close as Lost");
            }

            return(client.Execute(BrowserOptionHelper.GetOptions($"Opening opportunity close dialog"), driver =>
            {
                driver.WaitUntilVisible(By.XPath(AppElements.Xpath[AppReference.Dialogs.CloseOpportunity.Ok]));
                return true;
            }));
        }
示例#20
0
        public bool IsButtonAvailable(string name)
        {
            return(_app.Client.Execute(BrowserOptionHelper.GetOptions($"Check ribbon button"), driver =>
            {
                //Find the button in the CommandBar
                var ribbon = driver.WaitUntilAvailable(By.XPath(AppElements.Xpath[AppReference.CommandBar.Container]),
                                                       TimeSpan.FromSeconds(5));

                if (ribbon == null)
                {
                    ribbon = driver.WaitUntilAvailable(By.XPath(AppElements.Xpath[AppReference.CommandBar.ContainerGrid]),
                                                       TimeSpan.FromSeconds(5),
                                                       null,
                                                       () => // FailureCallback
                    {
                        throw new TestExecutionException(Constants.ErrorCodes.RIBBON_NOT_FOUND);
                    });
                }
                //Get the CommandBar buttons
                var items = ribbon.FindElements(By.TagName("button"));

                //Is the button in the ribbon?
                if (items.Any(x => x.GetAttribute("aria-label").Equals(name, StringComparison.OrdinalIgnoreCase)))
                {
                    return true;
                }
                else
                {
                    //Is the button in More Commands?
                    if (items.Any(x => x.GetAttribute("aria-label").Equals("More Commands", StringComparison.OrdinalIgnoreCase)))
                    {
                        //Click More Commands
                        items.FirstOrDefault(x => x.GetAttribute("aria-label").Equals("More Commands", StringComparison.OrdinalIgnoreCase)).Click(true);
                        driver.WaitForTransaction();

                        //Find the button
                        return driver.HasElement(By.XPath(AppElements.Xpath[AppReference.CommandBar.Button].Replace("[NAME]", name)));
                    }
                    else
                    {
                        return false;
                    }
                }
            }));
        }
示例#21
0
        public FormData OpenRecord(OpenFormOptions formOptions)
        {
            Logger.WriteLine($"Opening record {formOptions.EntityName} with ID {formOptions.EntityId}");
            App.Client.Execute(BrowserOptionHelper.GetOptions($"Open: {formOptions.EntityName}"), driver =>
            {

                driver.Navigate().GoToUrl(formOptions.GetUrl(driver, _currentAppId));
                CheckAlert(driver);
                HelperMethods.WaitForFormLoad(driver);

                if (App.Client.ScriptErrorExists())
                    throw new TestExecutionException(Constants.ErrorCodes.FORMLOAD_SCRIPT_ERROR_ON_FORM);

                return true;
            });

            return GetFormData(GlobalTestingContext.Metadata.GetEntityMetadata(formOptions.EntityName));
        }
示例#22
0
        /// <summary>
        /// Set Value
        /// </summary>
        /// <param name="field">The field</param>
        /// <param name="value">The value</param>
        /// <example>xrmApp.Entity.SetValue("firstname", "Test");</example>
        public static BrowserCommandResult <bool> SetValueFix(this WebClient client, string field, string value, ContainerType formContextType)
        {
            return(client.Execute(BrowserOptionHelper.GetOptions("Set Value"), driver =>
            {
                IWebElement fieldContainer = null;

                if (formContextType == ContainerType.Body)
                {
                    // Initialize the entity form context
                    var formContext = driver.WaitUntilAvailable(By.XPath(AppElements.Xpath[AppReference.Entity.FormContext]));
                    fieldContainer = formContext.WaitUntilAvailable(By.XPath(AppElements.Xpath[AppReference.Entity.TextFieldContainer].Replace("[NAME]", field)));
                }
                else if (formContextType == ContainerType.Header)
                {
                    // Initialize the Header context
                    var formContext = driver.WaitUntilAvailable(By.XPath(AppElements.Xpath[AppReference.Entity.HeaderContext]));
                    fieldContainer = formContext.WaitUntilAvailable(By.XPath(AppElements.Xpath[AppReference.Entity.TextFieldContainer].Replace("[NAME]", field)));
                }
                else if (formContextType == ContainerType.Dialog)
                {
                    // Initialize the Dialog context
                    var formContext = driver.WaitUntilAvailable(SeleniumFunctions.Selectors.GetXPathSeleniumSelector(SeleniumSelectorItems.Dialog_Container));
                    fieldContainer = formContext.WaitUntilAvailable(By.XPath(AppElements.Xpath[AppReference.Entity.TextFieldContainer].Replace("[NAME]", field)));
                }

                IWebElement input;
                bool found = fieldContainer.TryFindElement(By.TagName("input"), out input);

                if (!found)
                {
                    found = fieldContainer.TryFindElement(By.TagName("textarea"), out input);
                }

                if (!found)
                {
                    throw new NoSuchElementException($"Field with name {field} does not exist.");
                }

                SetInputValue(driver, input, value);

                return true;
            }));
        }
示例#23
0
        /// <summary>
        /// Set Value
        /// </summary>
        /// <param name="field">The field</param>
        /// <param name="value">The value</param>
        /// <example>xrmApp.Entity.SetValue("firstname", "Test");</example>
        public static BrowserCommandResult <bool> SetValueFix(this WebClient client, string field, string value)
        {
            return(client.Execute(BrowserOptionHelper.GetOptions($"Set Value"), driver =>
            {
                var query = By.XPath(AppElements.Xpath[AppReference.Entity.TextFieldContainer].Replace("[NAME]", field));
                IWebElement fieldContainer = WaitUntilClickable(driver, query, TimeSpan.FromSeconds(5), null, null);

                if (fieldContainer == null)
                {
                    throw new TestExecutionException(Constants.ErrorCodes.ELEMENT_NOT_INTERACTABLE, $"Field {field} is probably locked or invisible");
                }

                IWebElement input;
                if (fieldContainer.FindElements(By.TagName("input")).Count > 0)
                {
                    input = fieldContainer.FindElement(By.TagName("input"));
                }
                else if (fieldContainer.FindElements(By.TagName("textarea")).Count > 0)
                {
                    input = fieldContainer.FindElement(By.TagName("textarea"));
                }
                else
                {
                    throw new Exception($"Field with name {field} does not exist.");
                }

                if (input != null)
                {
                    input.SendKeys(Keys.Control + "a");
                    input.SendKeys(Keys.Backspace);

                    if (!string.IsNullOrWhiteSpace(value))
                    {
                        input.SendKeys(value);
                    }

                    input.SendKeys(Keys.Tab + Keys.Tab);
                }

                return true;
            }));
        }
示例#24
0
        /// <summary>
        /// Generic method to help click on any item which is clickable or uniquely discoverable with a By object.
        /// </summary>
        /// <param name="by">The xpath of the HTML item as a By object</param>
        /// <returns>True on success, Exception on failure to invoke any action</returns>
        public static BrowserCommandResult <bool> SelectTabFix(this WebClient client, string tabName, string subTabName = "", int thinkTime = Microsoft.Dynamics365.UIAutomation.Browser.Constants.DefaultThinkTime)
        {
            client.Browser.ThinkTime(thinkTime);

            return(client.Execute(BrowserOptionHelper.GetOptions($"Select Tab"), driver =>
            {
                IWebElement tabList = driver.WaitUntilAvailable(By.XPath(AppElements.Xpath[AppReference.Entity.TabList]));

                ClickTab(driver, tabList, ".//li[@title='{0}']", tabName);

                //Click Sub Tab if provided
                if (!string.IsNullOrEmpty(subTabName))
                {
                    ClickTab(driver, tabList, AppElements.Xpath[AppReference.Entity.SubTab], subTabName);
                }

                driver.WaitForTransaction();
                return true;
            }));
        }
示例#25
0
        private static BrowserCommandResult <bool> HandleSaveDialog(this WebClient client)
        {
            //If you click save and something happens, handle it.  Duplicate Detection/Errors/etc...
            //Check for Dialog and figure out which type it is and return the dialog type.

            //Introduce think time to avoid timing issues on save dialog
            client.Browser.ThinkTime(1000);

            return(client.Execute(BrowserOptionHelper.GetOptions($"Validate Save"), driver =>
            {
                //Is it Duplicate Detection?
                if (driver.HasElement(By.XPath(AppElements.Xpath[AppReference.Entity.DuplicateDetectionWindowMarker])))
                {
                    if (driver.HasElement(By.XPath(AppElements.Xpath[AppReference.Entity.DuplicateDetectionGridRows])))
                    {
                        //Select the first record in the grid
                        driver.FindElements(By.XPath(AppElements.Xpath[AppReference.Entity.DuplicateDetectionGridRows]))[0].Click(true);

                        //Click Ignore and Save
                        driver.FindElement(By.XPath(AppElements.Xpath[AppReference.Entity.DuplicateDetectionIgnoreAndSaveButton])).Click(true);
                        driver.WaitForTransaction();
                    }
                }

                //Is it an Error?
                if (driver.HasElement(By.XPath("//div[contains(@data-id,'errorDialogdialog')]")))
                {
                    var errorDialog = driver.FindElement(By.XPath("//div[contains(@data-id,'errorDialogdialog')]"));

                    var errorDetails = errorDialog.FindElement(By.XPath(".//*[contains(@data-id,'errorDialog_subtitle')]"));

                    if (!String.IsNullOrEmpty(errorDetails.Text))
                    {
                        throw new InvalidOperationException(errorDetails.Text);
                    }
                }


                return true;
            }));
        }
        private static bool OpenOpportunityCloseDialog(WebClient client, bool closeAsWon)
        {
            return(client.Execute(BrowserOptionHelper.GetOptions($"Opening opportunity close dialog"), driver =>
            {
                string xPathQuery = String.Empty;
                if (closeAsWon)
                {
                    xPathQuery = AppElements.Xpath[AppReference.Entity.CloseOpportunityWin];
                }
                else
                {
                    xPathQuery = AppElements.Xpath[AppReference.Entity.CloseOpportunityLoss];
                }

                var closeBtn = driver.WaitUntilAvailable(By.XPath(xPathQuery), "Opportunity Close Button is not available");
                closeBtn?.Click();
                driver.WaitUntilVisible(By.XPath(AppElements.Xpath[AppReference.Dialogs.CloseOpportunity.Ok]));

                return true;
            }));
        }
示例#27
0
        private void WaitUntilSaveCompleted()
        {
            _app.Client.Execute(BrowserOptionHelper.GetOptions($"WaitUntilSaveCompleted"), driver =>
            {
                var timeout        = DateTime.Now.AddSeconds(20);
                bool saveCompleted = false;
                while (!saveCompleted && DateTime.Now < timeout)
                {
                    var saveStatus = driver.FindElement(SeleniumFunctions.Selectors.GetXPathSeleniumSelector(SeleniumSelectorItems.Entity_SaveStatus));

                    if (!string.IsNullOrEmpty(saveStatus.Text) && saveStatus.Text.ToLower() == "- saving")
                    {
                        Logger.WriteLine("Save not yet completed. Waiting..");
                        Thread.Sleep(500);
                    }
                    else if (!string.IsNullOrEmpty(saveStatus.Text) && saveStatus.Text.ToLower() == "- unsaved")
                    {
                        var formNotifications = GetFormNotifications();
                        throw new TestExecutionException(Constants.ErrorCodes.FORM_SAVE_FAILED, $"Detected Unsaved changes. Form Notifications: {string.Join(", ", formNotifications)}");
                    }
                    else
                    {
                        Logger.WriteLine("Save sucessfull");
                        saveCompleted = true;
                    }
                }

                if (!saveCompleted)
                {
                    throw new TestExecutionException(Constants.ErrorCodes.FORM_SAVE_TIMEOUT, 20);
                }


                return(true);
            });
        }
示例#28
0
        /// <summary>
        /// Sets the value of a Date Field.
        /// </summary>
        /// <param name="field">Date field name.</param>
        /// <param name="value">DateTime value.</param>
        /// <param name="formatDate">Datetime format matching Short Date formatting personal options.</param>
        /// <param name="formatTime">Datetime format matching Short Time formatting personal options.</param>
        /// <example>xrmApp.Entity.SetValue("birthdate", DateTime.Parse("11/1/1980"));</example>
        public static BrowserCommandResult <bool> SetValueFix(this WebClient client, string field, DateTime?value, bool dateOnly, string formatDate = null, string formatTime = null)
        {
            return(client.Execute(BrowserOptionHelper.GetOptions($"Set Date/Time Value: {field}"), driver =>
            {
                driver.WaitForTransaction();

                var container = driver.WaitUntilAvailable(
                    SeleniumFunctions.Selectors.GetXPathSeleniumSelector(SeleniumSelectorItems.Entity_DateContainer, field),
                    $"Field: {field} does not exist");

                var dateField = container.WaitUntilAvailable(
                    SeleniumFunctions.Selectors.GetXPathSeleniumSelector(SeleniumSelectorItems.Entity_DateTime_Time_Input),
                    $"Input for {field} does not exist");
                try
                {
                    var date = value.HasValue ? formatDate == null ? value.Value.ToShortDateString() : value.Value.ToString(formatDate) : string.Empty;
                    driver.RepeatUntil(() =>
                    {
                        ClearFieldValue(dateField, client.Browser);
                        dateField.SendKeys(date);
                    },
                                       d => dateField.GetAttribute("value") == date,
                                       new TimeSpan(0, 0, 9), 3
                                       );
                    driver.ClearFocus();
                    driver.WaitForTransaction();
                }
                catch (WebDriverTimeoutException ex)
                {
                    throw new InvalidOperationException($"Timeout after 10 seconds. Expected: {value}. Actual: {dateField.GetAttribute("value")}", ex);
                }

                // date only fields don't have a time control
                // clearing the date part of a datetime field is enough to clear both
                if (dateOnly || !value.HasValue)
                {
                    return true;
                }

                var timeFieldXPath = By.XPath($"//div[contains(@data-id,'{field}.fieldControl._timecontrol-datetime-container')]/div/div/input");
                var timeField = driver.WaitUntilAvailable(timeFieldXPath, TimeSpan.FromSeconds(5), "Time control of datetime field not available");
                try
                {
                    var time = value.HasValue ? formatTime == null ? value.Value.ToShortTimeString() : value.Value.ToString(formatTime) : string.Empty;
                    driver.RepeatUntil(() =>
                    {
                        ClearFieldValue(timeField, client.Browser);
                        timeField.SendKeys(time + Keys.Tab);
                    },
                                       d => timeField.GetAttribute("value") == time,
                                       new TimeSpan(0, 0, 9), 3
                                       );
                    driver.WaitForTransaction();
                }
                catch (WebDriverTimeoutException ex)
                {
                    throw new InvalidOperationException($"Timeout after 10 seconds. Expected: {value}. Actual: {timeField.GetAttribute("value")}", ex);
                }

                return true;
            }));
        }
示例#29
0
 public static void Login(WebClient client, Uri orgUri, SecureString username, SecureString password)
 {
     client.Execute(BrowserOptionHelper.GetOptions("Login"), Login, client, orgUri, username, password);
 }
示例#30
0
        public static BrowserCommandResult <bool> ClickCommand(this WebClient client, string name, string subname = null, string subSecondName = null)
        {
            return(client.Execute(BrowserOptionHelper.GetOptions($"Click Command"), driver =>
            {
                //Find the button in the CommandBar
                var ribbon = driver.WaitUntilAvailable(By.XPath(AppElements.Xpath[AppReference.CommandBar.Container]),
                                                       TimeSpan.FromSeconds(5));

                if (ribbon == null)
                {
                    ribbon = driver.WaitUntilAvailable(By.XPath(AppElements.Xpath[AppReference.CommandBar.ContainerGrid]),
                                                       TimeSpan.FromSeconds(5),
                                                       "Unable to find the ribbon.");
                }

                //Get the CommandBar buttons
                var items = ribbon.FindElements(By.TagName("button"));

                //Is the button in the ribbon?
                if (items.Any(x => x.GetAttribute("aria-label").Equals(name, StringComparison.OrdinalIgnoreCase)))
                {
                    items.FirstOrDefault(x => x.GetAttribute("aria-label").Equals(name, StringComparison.OrdinalIgnoreCase)).Click(true);
                    driver.WaitForTransaction();
                }
                else
                {
                    //Is the button in More Commands?
                    var moreCommands = items.FirstOrDefault(x => x.HasAttribute("data-id") && x.GetAttribute("data-id").Equals("OverflowButton", StringComparison.OrdinalIgnoreCase));
                    if (moreCommands != null)
                    {
                        //Click More Commands
                        moreCommands.Click(true);
                        driver.WaitForTransaction();

                        //Click the button
                        if (driver.HasElement(By.XPath(AppElements.Xpath[AppReference.CommandBar.Button].Replace("[NAME]", name))))
                        {
                            driver.WaitUntilClickable(By.XPath(AppElements.Xpath[AppReference.CommandBar.Button].Replace("[NAME]", name)), TimeSpan.FromSeconds(5), $"Unable to click on button: {name}").Click(true);
                            driver.WaitForTransaction();
                        }
                        else
                        {
                            throw new InvalidOperationException($"No command with the name '{name}' exists inside of Commandbar.");
                        }
                    }
                    else
                    {
                        throw new InvalidOperationException($"No command with the name '{name}' exists inside of Commandbar.");
                    }
                }

                if (!string.IsNullOrEmpty(subname))
                {
                    var submenu = driver.WaitUntilAvailable(By.XPath(AppElements.Xpath[AppReference.CommandBar.MoreCommandsMenu]));

                    var subbutton = submenu.FindElements(By.TagName("button")).FirstOrDefault(x => x.Text == subname);

                    if (subbutton != null)
                    {
                        subbutton.Click(true);
                    }
                    else
                    {
                        throw new InvalidOperationException($"No sub command with the name '{subname}' exists inside of Commandbar.");
                    }

                    if (!string.IsNullOrEmpty(subSecondName))
                    {
                        var subSecondmenu = driver.WaitUntilAvailable(By.XPath(AppElements.Xpath[AppReference.CommandBar.MoreCommandsMenu]));

                        var subSecondbutton = subSecondmenu.FindElements(By.TagName("button")).FirstOrDefault(x => x.Text == subSecondName);

                        if (subSecondbutton != null)
                        {
                            subSecondbutton.Click(true);
                        }
                        else
                        {
                            throw new InvalidOperationException($"No sub command with the name '{subSecondName}' exists inside of Commandbar.");
                        }
                    }
                }

                driver.WaitForTransaction();

                return true;
            }));
        }