How to determine the calling page in user control - c#

I have a user control which is in common in two asp.net pages how to find out the parent page i dont want to use the page's title is there any concrete way to determine may be a page's class or any way else
I would like to do this
if (this.page == "pagename")
{
//do this
}
else
{
//do this
}

You can use this.Page in order to find the current page and use this.Page.GetType() if you are expecting class name

You can use:
Page myParentPage = this.Page;
In your method.

Try this:
if (this.Page.GetType().Name.ToLower() == "pagename".Replace(".", "_").ToLower())
{
//do this
}
else
{
//do this
}

Related

How do I assert that an Element/Button is hidden on a page using Selenium C#?

I am trying to validate a scenario that for a specific user some web elements/buttons should be hidden on a page. I have done a quick-n-dirty implementation of a method to verify this and would like to know if there are better ways to do it. Please advice
public void ValidateThatButtonIsHidden(string button)
{
IWebElement theButton = null;
if (button.ToLower().Trim() == "submit an order")
{ theButton = FindElement(By.Id(_elementBtnId1)); }
else if (button.ToLower().Trim() == "validate order")
{ theButton = FindElement(By.Id(_elementBtnId2)); }
//Verifying that an element is not visible
Assert.False(IsELementVisible(theButton));
}
The idea is that user can call this method and pass the string from his/her test to validate the hidden element.
You can use the Displayed method to check the visibility of an element in a page.
If the element is visible in a page, then theButton.Displayed will return the value as true , else false will be written for the invisible element.
So, you can change your assertion as below
Assert.IsFalse(button.Displayed);
You can use InvisibilityOfElementLocated method in ExpectedConditions class coupled with ElementExists method. The idea is that if the element exists in the DOM but is still not visible, it must be hidden :
By your_locator = By.Id("foo");
Assert.IsTrue(ExpectedConditions.ElementExists(your_locator) && ExpectedConditions.InvisibilityOfElementLocated(your_locator));
This has been helpful for me. Works not just for checking invisibility but also for enable/not enabled, present/not present etc:
private enum ElementStatus{
VISIBLITY,
NOTVISIBLE,
ENABLED,
NOTENABLED,
PRESENCE,
ABSENT
}
private ElementStatus isElementVisible(WebDriver driver, By by,ElementStatus getStatus){
try{
if(getStatus.equals(ElementStatus.ENABLED)){
if(driver.findElement(by).isEnabled())
return ElementStatus.ENABLED;
return ElementStatus.NOTENABLED;
}
if(getStatus.equals(ElementStatus.VISIBLITY)){
if(driver.findElement(by).isDisplayed())
return ElementStatus.VISIBLE;
return ElementStatus.NOTVISIBLE;
}
return ElementStatus.PRESENT;
}catch(org.openqa.selenium.NoSuchElementException nse){
return ElementStatus.ABSENT;
}
}
I evaluated all solutions suggested here, but was faced with the challenge that (I should have mentioned we have angular pages as well), that sometimes the Elements which were supposed to be hidden were actually absent from DOM.
As I was not able to find elements and also I wanted the method to be reusable/scalable for other tests should I ever have to test another hidden button/element. This is what I did, and it is worth mentioning that I am using Specflow to parameterize my tests.
public bool IsElementPresent(By by)
{
try
{
driver.FindElement(by);
return true;
}
catch (NoSuchElementException)
{
return false;
}
}
public void ThatButtonIsHidden(string p0)
{
if (p0.ToLower().Trim() == "submit an order")
{
bool isBtnPresent = IsElementPresent(By.Id("btn1Id"));
Assert.IsFalse(isBtnPresent);
}
else if (p0.ToLower().Trim() == "validate order")
{
bool isBtnPresent = IsElementPresent(By.Id("btn2Id"));
Assert.IsFalse(isBtnPresent);
}
}
Hope this helps. Works perfectly for me to handle the situation.

How to I get ASP.NET Page Name

Easy one here.
I have a control inside a control inside a masterpage. The page name looks something like this in HTML
ctl00$MasterPageBody$MainControl$ChildControl
Any idea how I can get the above from code behind?
Thanks!
It's the clientID property of the control.
If we're talking about a top-level control on the page, or at least one that isn't in any sort of repeating type, you can just use the ClientID property.
<asp:Label runat="server" ID="testLabel" />
<script>
$('#<%= testLabel.ClientID %>').click(function() { ... });
</script>
If we're talking about something that isn't accessible directly like that, you'll have to do the same thing, but it'll have to be wrapped in a FindControl. The example of that isn't so clean, so I'll trust you can understand from my words. But basically, if you have a label that shows code-behind-given text on each row of a GridView, you'll have to call ((Label)e.Row.FindControl("testLabel")).ClientID. Still pretty straight-forward, but a bit more complicated than the first case.
You should use a function similar to this:
public static Control FindControlRecursive(Control ctl, string id) {
if (!ctl.HasControls())
return null;
Control res = null;
foreach(Control c in ctl.Controls) {
if (c.ID == id) {
res = c;
break;
} else {
res = FindControlRecursive(c, id);
if (res != null)
break;
}
}
return res;
}
in this way:
Control ChildControl = FindControlRecursive(this.Page, "ChildControl");
string ID = ChildControl.ClientID;

How To Compare My Actual MasterPage

I have 2 MasterPage in my project.
The MasterPage to common pages and the MasterPage to PopUp pages.
And I have a class BasePage that is inherited by all pages, and in BasePage I need to verify which is the actual MaterPage that is used.
Ex:
if(Master.GetType() == typeof(Master) ....
How do I test it?
The is operator is handy for checking types.
If the two masters (I will call them MasterPage and MasterPagePopup) are inherited form a common ancestor (Page?) and not one another, you could do something like this:
if(Master is MasterPage)
{ do some stuff; }
if(Master is MasterPagePopup)
{ do other stuff; }
The only gotcha is if one master is inherited from the other; if MasterPagePopup is inherited form MasterPage, then both cases above would be true for MasterPagePopup as he IS both a MasterPage and MasterPagePopup . However, if...else if would solve this:
if(Master is MasterPagePopup)
{ do other stuff; }
else if(Master is MasterPage) // popup is already handled and will not hit this
{do some stuff; }
The easiest way to check the type of your MasterPage is with the is keyword:
if (this.Master is MasterPageCommon) {
} else if (this.Master is MasterPagePopup) {
}
You should just be able to do
if(page.Master is PopUpMaster)
{
//Do Something
}
else if (page.Master is NormalMaster)
{
//Do Something
}

Get Textbox Value from Masterpage using c#

I have a search textbox situated on a masterpage like so:
<asp:TextBox ID="frmSearch" runat="server" CssClass="searchbox"></asp:TextBox>
<asp:LinkButton ID="searchGo" PostBackUrl="search.aspx" runat="server">GO</asp:LinkButton>
The code behind for the search page has the following to pick up the textbox value (snippet):
if (PreviousPage != null && PreviousPage.IsCrossPagePostBack)
{
Page previousPage = PreviousPage;
TextBox tbSearch = (TextBox)PreviousPage.Master.FindControl("frmSearch");
searchValue.Text = tbSearch.Text;
//more code here...
}
All works great. BUT not if you enter a value whilst actually on search.aspx, which obviously isn't a previous page. How can I get round this dead end I've put myself in?
If you use the #MasterType in the page directive, then you will have a strongly-typed master page, meaning you can access exposed properties, controls, et cetera, without the need the do lookups:
<%# MasterType VirtualPath="MasterSourceType.master" %>
searchValue.Text = PreviousPage.Master.frmSearch.Text;
EDIT: In order to help stretch your imagination a little, consider an extremely simple property exposed by the master page:
public string SearchQuery
{
get { return frmSearch.Text; }
set { frmSearch.Text = value; }
}
Then, through no stroke of ingenuity whatsoever, it can be seen that we can access it like so:
searchValue.Text = PreviousPage.Master.SearchQuery;
Or,
PreviousPage.Master.SearchQuery = "a query";
Here is a solution (but I guess its old now):
{
if (PreviousPage == null)
{
TextBox tbSearch = (TextBox)Master.FindControl("txtSearch");
searchValue.Value = tbSearch.Text;
}
else
{
TextBox tbSearch = (TextBox)PreviousPage.Master.FindControl("txtSearch");
searchValue.Value = tbSearch.Text;
}
}

Problem looping through web controls

I've got a web page where I am dynamically creating controls during Page_Load event (this is done so because I do not know how many controls I will need until session is active and certain variables are accessible)
I need to be able to loop through these controls to find Checkbox when a button click is processed. Looping through the Form.Controls does not appear to be sufficient. I would think that Request.Form might work but it does not appear to be accessible in my C# block?
What should code for Request.Form look like? OR
Has anyone done this before with dynamically created controls?
Any insight is appreciated.
Simplified Example from MSDN:
var myControl = FindControl("NameOfControl");
if(myControl != null)
{
//do something
}
else
{
//control not found
}
Hope this helps! ;)
Your controls will be accessible trough the Controls collection of their immediate parent. Unless you add them like Page.Form.Controls.Add (myControl);, you won't find it in Page.Form.Conttrols. If you add them to a place holder, you must find them in thePlaceHolder.Controls.
LinkButton myDynamicLinkButton = new myDynamicLinkButton ();
myDynamicLinkButton.ID = "lnkButton";
myPlaceHolder.Controls.Add (myDynamicLinkButton);
//........
LinkButton otherReferenceToMyLinkButton = myPlaceHolder.FindControl ("lnkButton");
As #David said in his comment, you should probably think about using a Repeater instead. It would probably simplify your case a lot.
Since the controls might be nested in other controls, you need to search recursively. You can use this method to find the control:
public Control FindControlRecursive(Control root, string id)
{
if (root.ID == id)
{
return root;
}
foreach (Control c in root.Controls)
{
Control t = FindControlRecursive(c, id);
if (t != null)
{
return t;
}
}
return null;
}
And you can implement it this way:
CheckBox check = FindControlRecursive(Page.Form, "CheckBox1");
You should have access to Request["xyz"] anywhere in your aspx.cs code. You can either find control as described above and read it's value or do so directly from Request using the Control.UniqueID property. For example if it's a checkbox that's within the repeater then the UniqueID would look like dtgData$ctl02$txtAmount
Thanks for the insight guys. I kind of took the discussion and ran with it and found my solution that worked best for me.
foreach(String chk in Request.Form)
{
if (chk.Contains("chkRemove"))
{
int idxFormat = chk.LastIndexOf("chkRemove");
objectname = chk.Substring(idxFormat);
}
}
Turned out really all I needed was the name. The string contained a number at the end which was needed to determine a position of datatable items. Thanks for the advice!

Categories