/// <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); }
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); }
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); }
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"; })); }
/// <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; })); }
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); }
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); }
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); }); }
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); });
/// <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; })); }
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; })); }
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; } } })); }
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)); }
/// <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; })); }
/// <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; })); }
/// <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; })); }
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; })); }
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); }); }
/// <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; })); }
public static void Login(WebClient client, Uri orgUri, SecureString username, SecureString password) { client.Execute(BrowserOptionHelper.GetOptions("Login"), Login, client, orgUri, username, password); }
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; })); }