Want to use one tag with different values according to the scenario in cucumber - selenium

we have a cleanup hook in our automation framework which tagged from the cucumber feature file
E.g
#cc_task_clean_up_hook_enrol_A
Scenario: Person can enrol_A
When I select the context menu
Then I am able to enroll the patient into 'enrol_A'
the implementation of the hook (#cc_task_clean_up_hook) is
#After(value = "#toc_task_clean_up_hook_enrol_A", order = HookOrder.CLEAN_UP_APP_AFTER)
public void cleanUpTOC() {
this.patientContextPage.selectedContextMenuItem("Pathway");
this.pathWayPage.selectReferences("Enroll in Pathway");
this.pathWayPage.deactivateEnrollment("enrol_A", "Withdrawn");
}
So exactly the same way we need an another scenario like
Scenario: Person can enroll_B
When I select the context menu
Then I am able to enroll the patient into 'enrollB'
So we can implement another hook as follows, the difference is the parameter type "enrollB"
#After(value = "#toc_task_clean_up_hook_enrollB", order = HookOrder.CLEAN_UP_APP_AFTER)
public void cleanUpTOC() {
this.patientContextPage.selectedContextMenuItem("Pathway");
this.pathWayPage.selectReferences("Enroll in Pathway");
this.pathWayPage.deactivateEnrollment("enrol_B", "Withdrawn");
}
So is it possible to consolidate these two methods and write only one generic clean up hook, based on the passed parameter? Your help is much appreciated.

You can add the scenario object to the arguments passed to the after hook. The framework will inject the currently executing scenario to the method.
public void afterMethod(Scenario scenario){}
You can use the getSourceTagNames() method of the Scenario object which will return you the collection of tags for the current executing scenario. From this collection you can determine if you have the tag ending with 'enroll_A' or 'enroll_B'.
Or you can use the getName() method which returns the description of the current scenario. So you will get either 'Person can enroll_A' or 'P..... enroll_B'. Just need to parse again.
You can modify the Then step to pass the enroll type to step definition. Store this in a variable. Use this variable in your after hook. But this will require the after hook to be in the same class.
Also you will need to change the value parameter of After hook to - {"#toc_task_clean_up_hook_enrollA,#toc_task_clean_up_hook_enrollB"}.
One observation that these two seem to have the same steps, if so then have you considered ScenarioOutline instead.

Related

What is the proper way to extend a Fixture with a Parameter Interface and add new parameters of a different type?

Let's assume I have a test fixture that inherits from ::testing::WithParamInterface<MyType> that uses it in SetUp().
class MyFixture : ..., ::testing::test, ::testing::WithParamInterface<MyType> {
virtual void SetUp() override {
auto param = GetParam();
...
}
};
I wish to write a text fixture that subclasses this, however will provide a param interface in addition to the one the current fixture provides. i.e. something like:
class SubclassedFixture : ..., MyFixture, ::testing::WithParamInterface<MySecondType> { ... };
Ideally this would then run all tests in MyFixture with the types specified in INSTANTIATE_TEST_CASE_P(..., MyFixture, {MyFixtureSpecifiedValues}). And then run all the tests in SubclassedFixture over the combinations INSTANTIATE_TEST_CASE_P(..., SubclassedFixture, {MyFixtureSpecifiedValues} x {SubclassedFixtureValues}).
A secondary goal here is to change as little code as possible in the already existing MyFixture class.
I do not expect anything in Google Test to neatly support this. However what would be the best way to restructure these tests to get this functionality, changing MyFixture at little as possible?

Pass multiple optional parameters to Controller Action

I have a controller Action that returns a list of activities to a view. (eventID,Venue,Room,EventDescription,EventType,StartDateTime,EndDateTime). The users wanted to be able to filter by Venue so I added Venue as id to the action method
ActionResult ListEvents(id string)
{
... Get the relevant details and return the view with the model
}
Now they want to also be able to filter by any/all of Event Type, Start, End, whether Post-event data has been completed.
Am I better to add these as GET query parameters or to define a custom route that will accept all 5 arguments or is there another solution
I will also need to add sorting and pagination at some point in case this changes the suggestion.
Typically, these would be handled via a query string, but it doesn't matter how you do it really. Regardless, of how the parameters are sent, your action simply needs to accept them all. The only thing you have to be aware of is the standard C# method rule (since actions are just methods) that optional parameters must be the last ones on the method. If they're all optional, then even that isn't really a concern.
Basically, you just have something like:
public ActionResult ListEvents(string id = null, int? eventID = null, ...)
{
Then inside, you'd just do something like:
var events = db.Events;
if (eventID.HasValue)
{
events = events.Where(m => m.EventID == eventId);
}
// rinse and repeat for each filter

I want to automate a scenario in which multiple products needs to be asserted with respect to filter values from a ecommerce website?

I want to automate a scenario in which multiple products needs to be asserted with respect to filter values from a ecommerce website. I want to know what could be the approach which we can implement using selenium?
hi plz try like below
public class ComparingItems {
public static void main(String[] args) {
// Multiple products
String mProducts[] = {"Reebok","addidas","puma"};
// filter values from e commerce website
String eProducts[] = {"Reebok","Fila","puma"};
// now how to assert the two use below logic
for(int i=0;i< mProducts.length;i++){
Assert.assertEquals(mProducts[i], eProducts[i], "Item Not matched");
}
}
}
**RegressionTestSuite**
#test
1)filter1
#test
2)filter2
#test
3)filter3
#test
4)filter1 and filter2
#test
5)filter1 and filter3
#test
6)filter2 and filter3
*CommonOperations class* //abstract class
void selectCategories(String variable){}
void setFilterCriteria(filter1, filter2, filter3){}
void hoverProduct(){}
void clickAndViewDetails() {}
// there could be many more methods which are common to finding product details across the website.
FilterTypeMobile interface
{void getMobileDetails(){}
filter variable common to mobile phones
}
class TelevisionProduct implements FilterTypeTelevision
{#overridden
void getTelevisionDetails(){}
}
FilterTypeTelevision interface
{void getTelevisionDetails(){}
filter variable common to Televisions
}
class MobileProduct implements FilterTypeMobile
{#overridden
void getMobileDetails(){}
}
I have basically written basic framework without impplementation. Right now I am just deciding on the strategy to achieve automation.
You can develop a framework for same, here are a few best practices which I follow:
Make good use of Test Execution frameworks. I use TestNG.
I create a base file which makes use of most of the TestNG annotations for Setting and Tearing up.
Separate your Re-usable functions and call it wherever needed. I generally add these in the base class.
I personally prefer keeping locators too in the base file if they are too complicated. This would help you to change the locator from one place and get reflected for all. In this case, do follow a good naming convention.
Use collections wherever possible.
You can use something like ReportNG for more user friendly reports.
Make more use of implicit waits and avoid using JavascriptExecutors.
Copy the Drivers and libraries within the project folders for better mobility and less external dependencies.
Adding selenium WD javadoc to your project will be of some help.
We also make sure we have a screenshot for failed test case by over-riding the onTestFailure method.
Rest all are simple coding basics for cleaner and easy to understand code that I believe you'll be following anyway.
Also, this may not be the best place to post such query as per regulations of this forum. But still I believe my answer is of some help.

Overload of actions in the controller

Is it possible to do an overload of the actions in the controller? I haven't found any info about it and when I tried, I got this error:
The current request for action 'Create' on controller type 'InterviewController' is >ambiguous between the following action methods:
System.Web.Mvc.ViewResult Create() on type >MvcApplication4.MvcApplication4.InterviewController
System.Web.Mvc.ViewResult Create(Int32) on type >MvcApplication4.MvcApplication4.InterviewController
I've tried to do this on another way and I also get a new error that I can't fix. In fact, I created a new action (called create_client instead of create)
I need 2 ways of creating an "opportunite".
I just call the action, and I receive an empty formular in which I just have to insert data.
From a client's page, I must create an "opportunite" with the client that's already completed when the form is displayed to the user. (there is a need of productivity, the user must perform actions as fast as possible).
In the table "opportunite", I've got a column called "FK_opp_client", which is equal to the column "idClient" from the client's table.
I don't get how I can do the second way.
I've created a new action in the controller.
'
' GET: /Opportunite/Create_client
Function Create_client(idclient) As ViewResult
'Dim FK_Client = (From e In db.client
'Where(e.idClient = idclient)
' Select e.nomCompteClient).ToString()
'ViewBag.FK_client = New SelectList(db.client, "idClient", "nomCompteClient", idclient)
Dim opportunite As opportunite = db.opportunite.Single(Function(o) o.idOpportunite = 5)
opportunite.FK_Client = idclient
ViewBag.FK_Client = New SelectList(db.client, "idClient", "nomCompteClient", opportunite.FK_Client)
Return View(opportunite)
End Function
I've tried a few things to get what I wanted, the last one was to copy what was done in the "Edit" action, but for an empty rank. (so I created an empty rank in my DB). I don't think it was a good idea (imagine someone wants to update the DB where idOpportunite = 5...)
Any better ideas?
If you want to keep those two methods under the same name, you will have to implement an ActionSelectionAttribute to decorate them, or use them with different verbs (for example POST and PUT). Please read more details on action method selection process here (old but still true).
Different approach might be making your parameter optional and make action to check if it has been passed or not (through nullable type).

Stored Proc in RIA Services

I want to load some data with a SP.
I've put a SP in a Linq to SQL Class and I don't know how to use it for loading it's data in a datagrid.
In LinqToSqlDomainService I can't figure out how to call a SP.
What steps should I use.
Any samples of this ? All samples use a table.
Thank's
This post should hopefully be of help:
http://blogs.msdn.com/brada/archive/2009/08/24/business-apps-example-for-silverlight-3-rtm-and-net-ria-services-july-update-part-24-stored-procedures.aspx
You can create empty view with the same structure of your sproc and map that stored procedure to your function in your DomainService
See sample on http://cid-289eaf995528b9fd.skydrive.live.com/self.aspx/Public/sproc.zip
I found the following excellent step-by-step guide at this site -
http://betaforums.silverlight.net/forums/p/218383/521023.aspx
1) Add a ADO Entity Data Model to your Web project; Select generate from database option; Select your Database instance to connect to.
2) Choose your DB object to import to the Model. You can expand Table node to select any table you want to import to the Model. Expand Stored Procedure node to select your Stored Precedure as well. Click Finish to finish the import.
3) Right click the DB model designer to select Add/Function Import. Give the function a name (same name as your SP would be fine) and select the Stored Procedure you want to map. If your SP returns only one field, you can map the return result to a collection of scalars. If your SP returns more than one field, you could either map the return result to a collection or Entity (if all the field are from a single table) or a collection of Complex types.
If you want to use Complex type, you can click Get Column button to get all the columns for your SP. Then click Create new Complex type button to create this Complex type.
4) Add a Domain Service class to the Web project. Select the DataModel you just created as the DataContext of this Service. Select all the entitis you want expose to the client. The service functions should be generated for those entities.
5) You may not see the Complex type in the Entity list. You have to manully add a query function for your SP in your Service:
Say your SP is called SP1, the Complex type you generated is called SP1_Result.
Add the following code in your Domain Service class:
public IQueryable<SP1_Result> SP1()
{
return this.ObjectContext.SP1().AsQueryable();
}
Now you can compile your project. You might get an error like this: "SP1_Result does not have a Key" (if you not on RIA service SP1 beta). If you do, you need to do the following in the service metadata file:
Added a SP1_Result metadata class and tagged the Key field:
[MetadataTypeAttribute(typeof(SP1_Result.SP1_ResultMetadata))]
public partial class SP1_Result
{
internal sealed class SP1_ResultMetadata
{
[Key]
public int MyId; // Change MyId to the ID field of your SP_Result
}
}
6) Compile your solution. Now you have SP1_Result exposed to the client. Check the generated file, you should see SP1_Result is generated as an Entity class. Now you can access DomainContext.SP1Query and DomainContext.SP1_Results in your Silverlight code. You can treat it as you do with any other Entity(the entity mapped to a table) class.
Calling a stored procedure is trivial. Import it as a function and then invoke the function as a member of the DDS. The return value is an ObservableCollection<> that you can use to set up the DataContext of the object you want to bind.
...unless you want to use it in a Silverlight RIA app via the magic code generated proxy, in which case your goose is cooked unless your result rows exactly match one of the entities. If you can meet that criterion, edit the DomainService class and surface a method that wraps the ObjectContext method.