Question with respect to common methods for different page objects in Cucumber
Has anyone worked upon creating common methods which can be used across different page objects in cucumber.
Example: Click method.
I specify page objects in feature file (And I click on object o).
This in turns calls the step defination. In step defination, we have written a generic method for click (object o.click())
We also have a separate class where all the page objects are defined (eg: xpath of object o). Now the question is how to integrate, these page objects with the common step defination of click method.
If this is achievable, we only require to change the steps in feature file for different objects(object o to object b). Single click method will work for all different page objects, we just need to add xpath of these objects in common page object class.
Anyone worked upon achieving this ?
Its totally depend on your project framework in which you want to setup.
Yes it possible
Example:
PageOjectclass:
WebDriver driver = null;
private WebElement element = null;
private By By = null;
public PageOjectclass(WebDriver driver) {
this.driver = driver;
}
public static WebElement button_submit() throws Exception {
try {
element = driver.findElement(By.xpath("//h1[#class='txtCenter white ico30']"));
} catch (Exception e) {
AutomationLog.error("HomePageHeader Element not found");
throw (e);
}
return element;
}
CommonClass
public static void Customclick(WebElement e) {
e.click();
}
StepDefinationClass
#When("^testing$")
public void test() throws Throwable {
CommonClass.Customclick(PageOjectclass.button_submit());
}
Just take care of passing the webdriver initialized object, pass them with constructor etc
Related
I have the following class:
public class MyDialogSelect extends RunBase
{
private DialogField nameField;
// Snipped for brevity
public Object dialog()
{
Dialog dialog = super();
nameField = dialog.addField(extendedTypeStr(CustName));
// Snipped for brevity
return dialog;
}
public void dialogSelectCtrl()
{
CustTable customerTable = CustTable::find(accountField.value());
nameField.value(customerTable.name());
// Snipped for brevity
}
}
This compiles and works as expected.
However, I prefer using the keyword this to indicate when variables belong to the instance, so I try changing it this to:
public class MyDialogSelect extends RunBase
{
private DialogField nameField;
// Snipped for brevity
public Object dialog()
{
Dialog dialog = super();
this.nameField = dialog.addField(extendedTypeStr(CustName));
// Snipped for brevity
return dialog;
}
public void dialogSelectCtrl()
{
CustTable customerTable = CustTable::find(accountField.value());
this.nameField.value(customerTable.name());
// Snipped for brevity
}
}
But, this won't compile, instead resulting in Invalid token '('..
However, if I remove this before nameField.value(customerTable.name());,
it works as expected again. (Note: I still indicate this in this.nameField = dialog.addField(extendedTypeStr(CustName));).
Why won't it compile when I include this before a property which invokes a method?
I've also observed this with this.nameField.enabled(false) also failing.
Is there a more general rule or principle I should understand here about when x++ allows, disallows, or requires this?
You cannot use this to reference instance variables in X++. Like in C++.
You can (and must) use this to refer to instance methods.
This refers to the context of the development, in your example, this refers to the class as a whole. Of you add another method, you would call that method using this.
With latest form pattern changes, I believe the MSFT recommendation is to use dialog form pattern instead of class to generate dialog.
I am working with the Contoso University tutorial and was trying it with both a modular attempt (separate projects for Models, DAL and WebUI - top picture in the attached picture) and a single project (containing all layers - bottom picture). In both cases the solution compiles without errors. However when I go to the details section for a student in web browser the modular project throws an error when I go to the second break point, starting:
Exception Details:
System.NullReferenceException: Object reference not set to an instance of an object.
The same model is passed into the view for each project,
#model ContosoUniversity.Models.Student
And a null reference exception occurs after the line:
#foreach (var item in Model.Enrollments){
I thought it may have been a namespace conflict between the ContosoUniversity.Models project and the Models folder in the ContosoUniversity project, however renaming the folder doesn't resolve this. Is there something else related to multiple projects that would cause a null value (Enrollments.cs not being sent to the model) to be encountered here, but not for a single project?
If its something deeper in the code I can follow up with full view-code and model classes.
Screenshot of working and non working solutions in VS2015Community
Since this is such a commonly confusing error to new developers, I've authored a post on my blog to explain what the error means in detail and how to debug it. TL;DR: Object reference not set to an instance of an object is a runtime error (hence why your project compiles fine) that occurs when you're expecting a variable to be an instance of a particular class, but it actually resolves to null at runtime.
This commonly occurs when you're selecting an object from a database, but nothing matches, or you've neglected to initialize a property on your model that requires initialization, like a list. Based on the line of code you've posted, my guess is that either the model itself is null (perhaps because it's coming from the database and you're not checking for null before sending it to the view), or the Enrollments property is null because you've neglected to initialize it, or it's not marked as virtual if your model is an instance of an entity class.
Whenever you request a specific object from the database, you should always check for null and handle appropriately. For example, if you're working on a "detail" action, your code should look something like:
public ActionResult Detail(int id)
{
var foo = db.Foos.Find(id); // potentially null, if no matching id
if (foo == null)
{
return new HttpNotFoundResult();
}
return View(foo);
}
If you have a list-style property on your model, you should always initialize it via the class constructor or a custom getter:
public class Foo
{
public Foo()
{
Bars = new List<Bar>();
}
public List<Bar> Bars { get; set; }
}
Or
public class Foo
{
private List<Bar> bars;
public List<Bar> Bars
{
get
{
if (bars == null)
{
bars = new List<Bar>();
}
return bars;
}
set { bars = value; }
}
}
If you're utilizing C# 6, the last one can be simplified to:
public class Foo
{
public List<Bar> Bars { get; set; } = new List<Bars>();
}
Finally, this is not necessary if you're dealing with an Entity Framework POCO, as long as the property is virtual:
public virtual ICollection<Bar> Bars { get; set; }
As part of the lazy-loading facility, Entity Framework automatically overrides the property such that it will never be null, only an empty collection if there's truly nothing there. However, if you neglect the virtual keyword, EF cannot do the necessary override to handle this.
Long and short, you need to figure out what variable is null that you're expecting to have an actual value, and then either do proper null-checking (which is a good idea regardless) or figure out why it's null instead of the value you expect.
I want to create a code in C# for Private constructor.
I want that it should allow only one object to be created but when I try to create more than one a message showing no more object can be created should be shown.
I don't want to use static constructor in this code.
How do I do that in C#?
You may use static counter or flag that will be set in your private counstructor to show that at least one instance were created.
But first of all, I suggest you to pay attention to Singleton pattern.
Simple, this is the classic singleton pattern:
public class MyClass
{
public static MyClass Instance;
private MyClass()
{
if (Instance != null)
throw new InvalidOperationException("no more object can be created");
// do other constructor logic
Instance = this;
}
}
Please note that synchronization has been left out. This code need synchronization for thread safe purpose.
I am using the basic instructions (here) for creating a property driven by a custom ToolPart.
All is good, except for the part where, in order to access the webpart property within the ApplyChanges method I must cast the "this.ParentToolPane.SelectedWebPart" back to a concrete "SimpleWebPart" class.
public override void ApplyChanges()
{
SimpleWebPart wp1 = (SimpleWebPart)this.ParentToolPane.SelectedWebPart;
// Send the custom text to the Web Part.
wp1.Text = Page.Request.Form[inputname];
}
Doing this means that I must pair each toolpart with a specific webpart. Is there a better way?
I cannot create an interface as there is no way of specifying a property in one.
I ineptly tried an passing an event/eventhandler during toolpart creation, but that did not update the webpart property when called.
I could create a base class for all the webparts that have a public "Text" property, but that is fugly.
I could also get desperate and crack open the this.ParentToolPane.SelectedWebPart reference with Reflection and call any properties named "Text" that way.
Either way, I am staring down the barrel of a fair bit of faffing around only to find out each option is a dead end.
Has anyone done this and can recommend the correct method for creating a reusable toolpart?
I have used an interface instead of a specific instance of a webpart.
private class IMyProperty
{
void SetMyProperty(string value);
}
public override void ApplyChanges()
{
IMyProperty wp1 = (IMyProperty)this.ParentToolPane.SelectedWebPart;
// Send the custom text to the Web Part.
wp1.SetMyProperty(Page.Request.Form[inputname]);
}
But this does not give a compile time warning that the toolpart requires the parent webpart to implement the IMyProperty interface.
The simple solution to that is to add a property of the IMyProperty interface in the toolpart constructor and call this reference instead of the this.ParentToolPane.SelectedWebPart property.
public ToolPart1(IContentUrl webPart)
{
// Set default properties
this.Init += new EventHandler(ToolPart1_Init);
parentWebPart = webPart;
}
public override void ApplyChanges()
{
// Send the custom text to the Web Part.
parentWebPart.SetMyProperty(Page.Request.Form[inputname]);
}
public override ToolPart[] GetToolParts()
{
// This is the custom ToolPart.
toolparts[2] = new ToolPart1(this);
return toolparts;
}
This works fine, but I cannot get over the feeling that there is something nasty in the underlying SharePoint code that may trip me up later.
I have some button on my form. When I click on every buttons run new form with same buttons. When I am clicking many times, show error OutOfMemory.
I think this is because I create a lot of form objects.
May be can clear stack or use form from stack if form is there?
You are keeping pointers (references) to old components which causes a memory leak. Make sure never to store components as members of your class unless you clear them later.
you need to use the Singleton pattern for your code. In Singleton Pattern, It will create only one object of your Form Class. If the object is null then it will create a new one else , it will return the current one. For this kindly refer to following code.
// Private Constructor
private static myForm thisForm = null;
private myForm()
{
thisForm = this;
}
// Now to Create Object, you need to create following getInstance Method
public static myForm getInstance()
{
if ( thisForm == null )
{
thisForm = new myForm();
}
return thisForm;
}
try above logic in your whole code. Your OutOfMemory Problem will 100% get solved.