CODEDUI c# Cannot clickSharePoint Ribbon Control - c#

As part of an automated test, I cannot click on the SharePoint Ribbon to select the "Alert Me" control. I am getting the following error:
Result Message:
Test method CodedUITestProject2.CodedUITest1.SetAlert threw exception:
Microsoft.VisualStudio.TestTools.UITest.Extension.FailedToPerformActionOnHiddenControlException: Cannot perform 'Click' on the hidden control. Additional Details:
TechnologyName: 'Web'
ControlType: 'Hyperlink'
TagName: 'A'
Id: 'Ribbon.Library.Share.AlertMe.Menu.Scope.AlertLibrary-Menu16'
Name: ''
Target: ''
InnerText: 'Set alert on this library'
---> System.Runtime.InteropServices.COMException: Exception from HRESULT: 0xF004F002
Please find my code below: 1. and 2. work and it errors out at 3. I've tried adding and subtracting different control settings.
//1. Select the Library Tab on the ribbon
UITestControl CLR = new UITestControl(browser);
CLR.TechnologyName = "Web";
CLR.SearchProperties.Add("InnerText", "LibraryLibrary Tools group. Tab 2 of 2.");
CLR.WaitForControlReady();
Mouse.Click(new Point(CLR.BoundingRectangle.X + CLR.BoundingRectangle.Width / 2, CLR.BoundingRectangle.Y + CLR.BoundingRectangle.Height / 2));
CLR.WaitForControlReady();
//Mouse.Click(CLR);
Playback.Wait(3000);
//2. set focus on the a pane control on the ribbon
UITestControl FRL = new UITestControl(browser);
FRL.TechnologyName = "Web";
FRL.SearchProperties.Add("TagName", "SPAN");
FRL.SearchProperties.Add("ControlType", "Pane");
FRL.SearchProperties.Add("Class", "ms-cui-groupTitle");
FRL.SearchProperties.Add("InnerText", "Share & Track");
FRL.WaitForControlExist();
FRL.SetFocus();
Mouse.Click(new Point(FRL.BoundingRectangle.X + FRL.BoundingRectangle.Width / 2, FRL.BoundingRectangle.Y + FRL.BoundingRectangle.Height / 2));
Playback.Wait(3000);
//3. Click on "Alert Me" ID
UITestControl AM = new UITestControl(browser);
AM.TechnologyName = "Web";
//AM.SearchProperties.Add("Inner Text", "Alert Me");
AM.SearchProperties.Add("Id", "Ribbon.Library.Share.AlertMe-Large");
AM.WaitForControlReady();
Mouse.Click(new Point(AM.BoundingRectangle.X + AM.BoundingRectangle.Width / 2, AM.BoundingRectangle.Y + AM.BoundingRectangle.Height / 2));
Playback.Wait(2000);

This is a common thing happens with SharePoint automation.
Two reasons could be keeping you back from clicking on the "Alert Me" link.
1. Alert me is kept under a parent and you are trying to click directly.
2. Two identical elements present where one is hidden and the other one is visible.
I will give code for the second reason, if it doesn't works then you can try clicking by following the parent child hierarchy which is very easy to perform by your own.
UITestControl AM = new UITestControl(browser);
//AM.TechnologyName = "Web";
//AM.SearchProperties.Add("Inner Text", "Alert Me");
AM.SearchProperties.Add("Id", "Ribbon.Library.Share.AlertMe-Large");
AM.WaitForControlReady();
UITestControlCollection uic=AM.FindMatchingControls();
foreach(UITestControl ui in uic)
{
if(ui.BoundingRectangle.Width !=-1)
{
Mouse.Click(ui);
break;
}
}
try above code. Else follow the parent child relationship. Also it is not recommended to use UITestControl all the time to identify the elements please try to use specific class names say for example if you are trying to click on hyperlink instead of UITestControl use HtmlHyperlink class so that you can use all possible attributes to identify the elements. This is a best practice which I follow.

Related

coded ui test project, obtain value of asp label

Created a simple calculator app in webforms.
User enters a number in a text field MainContent_numberTb and clicks on results button.
Added a new 'coded UI Test Project' to my solution. Have tested the UI by adding '5', This all works fine. Would now like to compare the actual result against the expected result.
BrowserWindow Browser = BrowserWindow.Launch("http://url");
UITestControl UiInputField = new UITestControl(Browser);
UiInputField.TechnologyName = "Web";
UiInputField.SearchProperties.Add("ControlType", "Edit");
UiInputField.SearchProperties.Add("Id", "MainContent_numberTb");
//Populate input field
Keyboard.SendKeys(UiInputField, "5");
//Results Button
UITestControl ResultsBtn = new UITestControl(Browser);
ResultsBtn.TechnologyName = "Web";
ResultsBtn.SearchProperties.Add("ControlType", "Button");
ResultsBtn.SearchProperties.Add("Id", "MainContent_calBtn");
Mouse.Click(ResultsBtn);
All above code works fine, problem occurs when trying to access the label
<asp:Label ID="AllNumLbl_Res" runat="server"></asp:Label>
What do I insert beside control type? It's not edit as edit is the text field. Then also, what stores the actual result so I can compare AllNumsTB?
string expectedAllNums = "1, 2, 3, 4, 5";
UITestControl AllNumsTB = new UITestControl(Browser);
AllNumsTB.TechnologyName = "Web";
AllNumsTB.SearchProperties.Add("ControlType", "?????");
AllNumsTB.SearchProperties.Add("Id", "MainContent_AllNumLbl_Res");
if(expectedAllNums != AllNumsTB.??????)
{
Assert.Fail("Wrong Answer");
}
UPDATE
OK so using the debugger console I was able to get the value of the label using ((Microsoft.VisualStudio.TestTools.UITesting.HtmlControls.HtmlSpan)new System.Collections.ArrayList.ArrayListDebugView(((System.Collections.CollectionBase)(AllNumsTB.FindMatchingControls()).List).InnerList).Items[0]).DisplayText
but when I use this in the code & ArrayListDebugView are inaccessible due to protection??
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
UPDATE
Thanks K Scandrett for the answer...If I may I was wondering could you also please help me with the validation...If the user enters a letter or a non positive number the error message will fire..
<asp:RegularExpressionValidator ID="regexpName"
//VALIDATION MESSAGE
UITestControl PositiveNumValMsg = new UITestControl(Browser);
PositiveNumValMsg.TechnologyName = "Web";
PositiveNumValMsg.SearchProperties.Add("Id", "MainContent_regexpName");
This all works fine, however I want to test if the label appears or not...so far I have tried
//bool visible = false;
//System.Drawing.Point p;
//// If the control is offscreen, bring it into the viewport
//PositiveNumValMsg.EnsureClickable();
// // Now check the coordinates of the clickable point
// visible = PositiveNumValMsg.TryGetClickablePoint(out p)
// && (p.X > 0 || p.Y > 0);
var isVisible = PositiveNumValMsg.WaitForControlPropertyNotEqual(UITestControl.PropertyNames.State, ControlStates.Invisible);
but they all return true even when the label is not shown, but it is still on the page just set to invisible. In that case I should check its style..something like
//string labelText3 = PositiveNumValMsg.GetProperty("style").ToString();
then check if the style contains visibility: visible?
You want to grab its InnerText property.
It's not mandatory to set ControlType, so some variation of the following should work:
UITestControl AllNumsTB = new UITestControl(Browser);
AllNumsTB.TechnologyName = "Web";
AllNumsTB.SearchProperties.Add(HtmlControl.PropertyNames.Id, "MainContent_AllNumLbl_Res");
var result = AllNumsTB.GetProperty(HtmlLabel.InnerText).Trim();
// var result = AllNumsTB.GetProperty("InnerText").Trim();
OR from https://social.msdn.microsoft.com/Forums/en-US/69ea15e3-dcfa-4d51-bb6e-31e63deb0ace/how-to-read-dynamic-text-from-label-using-coded-ui-for-web-application?forum=vstest:
var AllNumsTB = new HtmlLabel(Browser);
AllNumsTB.TechnologyName = "Web";
AllNumsTB.SearchProperties.Add(HtmlControl.PropertyNames.Id, "MainContent_AllNumLbl_Res");
var result = AllNumsTB.InnerText;
string result2;
// you may need to include this section, or you may not
if (result.Length > 0)
{
AllNumsTB.WaitForControlReady();
result2 = AllNumsTB.InnerText;
}
EDIT: Regarding testing an ASP.Net Validator
I've been able to check whether the validator message is displayed with the following method:
1) Created a test asp.net page with a regex validator that requires exactly 2 digits:
<asp:TextBox ID="numberTb" runat="server"></asp:TextBox>
<asp:RegularExpressionValidator ID="regexpName" ControlToValidate="numberTb" ValidationExpression="\d{2}" runat="server" ErrorMessage="Please enter 2 digits"></asp:RegularExpressionValidator>
<asp:Button ID="Button1" runat="server" Text="Button" />
2) Ran the Coded UI Test builder and started recording =>
Clicked Input box; typed s; hit tab (the validator error message is showing).
3) Paused the Recorder.
4) Clicked "Generate Code" icon and give it a method name; clicked "Add and Generate" button.
5) Now I dragged and dropped the Crosshair icon onto the validator message. Scrolling down the list of options is the ControlDefinition. Right-clicked it and selected "Add Assertion...".
6) Changed the Comparator to "Contains"; the Comparison Value to " visible;"; and gave it an Assertion Failure message.
7) Clicked the "Generate Code" icon, gave it a method name, etc.
Now we have code that will test the validator by running two methods - first to enter the input and trigger (or not) the validator message; the second to test the validator's message visibility. I copied and pasted the generated code and used it to write another opposing test using " hidden;" when given correct input. Ran both tests, and they both passed.
You will end up with something like (have substituted values):
public void DigitValidatorMsgShownWithIncorrectStringInput()
{
#region Variable Declarations
HtmlSpan uIAtleast2digitsPane = this.UIHomePageMyASPNETApplWindow.UIHomePageMyASPNETApplDocument.UIAtleast2digitsPane;
#endregion
// Verify that the 'ControlDefinition' property of 'At least 2 digits' pane contains ' visible;'
StringAssert.Contains(uIAtleast2digitsPane.ControlDefinition, " visible;", "The validator was not shown");
}
Of course all this can be coded manually once you know what you're looking for.

Why does this added UI button's event not get called?

In developing a mod for Cities: Skylines, I have run across a problem.
Most of my code, as far as I can tell, works fine - but so far, I haven't got to test it. This is because it should all get called in sequence when a button I have added to the UI gets clicked. The click event on this button is not calling the handler I've assigned to it.
This is where I create the button:
public class LoadingExtension : LoadingExtensionBase
{
public override void OnLevelLoaded(LoadMode mode)
{
Debug.LogDebugMessage("Adding 'Generate City Report' button to UI");
// Get the UIView object. This seems to be the top-level object for most
// of the UI.
var uiView = UIView.GetAView();
// Add a new button to the view.
var button = (UIButton)uiView.AddUIComponent(typeof(UIButton));
// Set the text to show on the button.
button.text = "Generate City Report";
// Set the button dimensions.
button.width = 250;
button.height = 30;
// Style the button to look like a menu button.
button.normalBgSprite = "ButtonMenu";
button.disabledBgSprite = "ButtonMenuDisabled";
button.hoveredBgSprite = "ButtonMenuHovered";
button.focusedBgSprite = "ButtonMenuFocused";
button.pressedBgSprite = "ButtonMenuPressed";
button.textColor = new Color32(255, 255, 255, 255);
button.disabledTextColor = new Color32(7, 7, 7, 255);
button.hoveredTextColor = new Color32(7, 132, 255, 255);
button.focusedTextColor = new Color32(255, 255, 255, 255);
button.pressedTextColor = new Color32(30, 30, 44, 255);
// Enable button sounds.
button.playAudioEvents = true;
// Place the button.
button.transformPosition = new Vector3(-1.0f, 0.97f);
// Respond to button click.
// NOT GETTING CALLED
button.eventClick += ButtonClick;
}
public void ButtonClick(UIComponent component, UIMouseEventParameter eventParam)
{
Debug.LogWarningMessage("HIGH LOGIC: Beginning report generation.");
string now = DateTime.Now.ToFileTime().ToString();
string filepath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string filename = filepath + "\\CityReport-" + now + ".xlsx";
Output fileCreator = new Output(filename);
fileCreator.GenerateReport();
}
}
According to the documentation I've been following, using
button.eventClick += ButtonClick;
should add ButtonClick as the click handler for the button. However, clicking on the button does nothing. The debug message at the start of the handler (the "HIGH LOGIC" message) doesn't get displayed (note: the earlier debug message about adding the button to the UI does). No error messages are displayed either in the game's debug panel or in VS.
I have also tried using new MouseEventHandler(ButtonClick), since the VS inline documentation tells me that the type of eventClick is MouseEventHandler. This doesn't show any errors in VS or the game, but doesn't work either.
(Note: there is official documentation, but it's next to useless.)
Does anyone here have experience with the C:S API? Why is this event not getting called?
You might try taking a small step back to check if a different UI element works; for example, by following the example for adding a UILabel. Registering a click event handler to this one possibly might work, since there's an actual example to follow; although, the documentation says to place this code inside the Start method. I'm not sure, but maybe the UIButton in your code should be placed in a Start method as well.
As an aside, I stumbled upon this link for debugging. Skylines seems to have its own messaging system for debugging.
Something that I did notice in your code is that the first Debug statement uses a different method than the second Debug statement:
Debug.LogDebugMessage("Adding 'Generate City Report' button to UI");
Debug.LogWarningMessage("HIGH LOGIC: Beginning report generation.");
It might not make any difference, but I would test out that Debug.LogWarningMessage call by moving it where the Debug.LogDebugMessage is to see if it actually works.
According to the extremely terse documentation there's a log file called output_log.txt, perhaps there might be some info contained within this file.
Have you tried:
//button.eventClick += ButtonClick;
button.eventClick += (c,e) => {
Debug.LogWarningMessage("HIGH LOGIC: Beginning report generation.");
string now = DateTime.Now.ToFileTime().ToString();
string filepath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string filename = filepath + "\\CityReport-" + now + ".xlsx";
Output fileCreator = new Output(filename);
fileCreator.GenerateReport();
};
Also have you tried doing this?:
//var button = (UIButton)uiView.AddUIComponent(typeof(UIButton));
var button = uiView.AddUIComponent(typeof(UIButton)) as UIButton
(Sorry, i can't coment yet)
It looks like your click handler, as such, is OK. Change your ButtonClick method to:
public void ButtonClick(UIComponent component, UIMouseEventParameter eventParam)
{
Debug.LogWarningMessage("HIGH LOGIC: Beginning report generation.");
}
and then check the debug output. If you have a bug after that line, then the debug message may not be visible.

Get clientID for multi userControl with same Server ID

I have ASP.Net application that have multiple User Controls in the same page every one have its hidden field that holds a value, and every one have button that calls pop-up and through this value from hidden field to it.
The problem that when i try to access the hidden field and get the value inside , the program always get the last one (which created last).
How can i get the value of the inner hidden field in the current UserControl (Which i'm clicking the button from)?
Attempts:
var hdnRegion = "<%=hdnRegionId.ClientID%>";
var regionIdVal = $("#" + hdnRegion).val();
methodName(regionIdVal);
another one:
var currentControl = "<%=this.ClientID%>";
var hdnRegion = currentControl + "_" + "hdnRegionId";
var regionIdVal = $("#" + hdnRegion).val();
methodName(regionIdVal);
I also tried to call a property from code behind that returns the value and one that returns the whole control with no correct result.
Any suggestions would be appreciated...
Accourding to your comment under the question, your btnUpdate and hdnRegionId controls are in the same container (for instance in the same div) so try this:
$('input[id*="btnUpdate"]').click(function(){
var regionIdVal = $(this).parent().children('input[id*="hdnRegionId"]').val();
methodName(regionIdVal);
});
This is a JSFiddle Demo that simulate your HTML code that is rendered by ASP.NET.

How to append a link label to an existing label?

I have a label inside a panel to display simple text. Now I have a link label that is added dynamically that displays some more information. How can I show this link label right next to the label text at run time? For example, the lable displays
A record is added.
I need to show with a link label "View Additional Details" next to the label text.
A record is added. View Additional Details
I have the code as below but it overlaps the existing label text. Thanks for any help!
LinkLabel details = new LinkLabel();
details.Text = "View Additional Details";
LinkLabel.Link link = new LinkLabel.Link();
link.LinkData = infoDetails;
details.Links.Add(link);
details.LinkClicked += new LinkLabelLinkClickedEventHandler(details_LinkClicked);
//Adding the link label control to the existing label control
lblInfo.Visible = true;
lblInfo.AutoSize = true;
lblInfo.Controls.Add(details);
Why are you trying to add a LinkLabel to a label? Add the LinkLabel to the same form as the label, and set the location of the LinkLabel appropriately.
In the example below, I'm assuming the code is being called from the form's class (or to a panel if you are using one). If not, replace this with your form instance. I'm setting the Y location as the same as lblInfo so the LinkLabel appears next to it. Adjust lblInfo.Margin.Right and details.Margin.Left as desired.
details.Margin.Left = 5;
details.Location = new Point(
lblInfo.Location.X + lblInfo.Width + lblInfo.Margin.Right + details.Margin.Left,
lblInfo.Location.Y
);
this.Controls.Add(details);
Update: changed padding to use Margin (thanks Anthony).

How do i bind an "Entry Cell" to a custom object using Xamarin?

I have been playing with Xamarin for a short time so far, and i just stumbled into something i couldn't find the answer into their documentation.
I am building a fairly simple app that retrieves "User Data" (username, email, password and so forth) from a RESTfull API and populates a listview with some of the data (This is the point i am at the moment. It works).
The next step is to build a "Edit User" screen, which is invoked uppon selecting (tapping) a user on the Listview i currently have.
I have managed to build a simple view that is basically two Entry Cells showing the data of the user picked into the previous listview screen. That also works.
The problem is that, once i edit the data into the "Entry Cell" it has no reflection into the "User Model" that populated the "entry cell" in first place.
How do i bind those together?
Code Sample:
// Entry Cell of Username (Should be Binded)
EntryCell ecUsername = new EntryCell()
{
Label = "Username:",
Placeholder = "username / login",
Text = _user.Username
};
// Entry Cell of Password (Should be Binded)
EntryCell ecEmail = new EntryCell ()
{
Label = "Email:",
Placeholder = "user email",
Text = _user.Email
};
Some Screenshots:
Once i click into a user, its data gets rendered into the next screen.
I haven't tested this, but something like this should work:
EntryCell ec = new EntryCell ();
ec.BindingContext = _user;
ec.SetBinding (EntryCell.TextProperty, "Username");

Categories

Resources