I wanted to add 3 items, completed 1 of them, then go to filter the 'completed' items.
In the end of execution, I saw more items added.
is this constructed wrong?
Feature: filter todo item
As a working adult with busy schedules
I want to use todo app to filter todo item
so that I can check todo item by status
Scenario Outline: Filter todo item
Given my todo list is empty
When I add "First todo item #1"
And I add "next todo item #2"
And I add "next todo item #3"
Then my todo list should has followings:
| <Item Displayed> |
When I complete "First todo item #1"
Then the todo item called "First todo item #1" should be marked as completed
And I filter the list to show Completed tasks
Then my todo list should has followings:
| <Item Displayed> |
Examples:
| Filter | Item Displayed |
| Completed | First todo item #1 |
| Active | next todo item #2 |
| Active | next todo item #3 |
error:
org.junit.ComparisonFailure: expected:<[tru]e> but was:<[fals]e>
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at todos.stepdefinitions.StepDefinitions.theTodoItemCalledShouldBeMarkedAsCompleted(StepDefinitions.java:88)
at ✽.the todo item called "First todo item #1" should be marked as completed
this is the steps definitions:
public class StepDefinitions {
#Steps
AddNewTodoActions addTodo;
#Steps
TodoListActions todoItems;
#Given("(?:.*) todo list is empty")
public void fresh_todo() {
navigate.toTheTodoMVCApplication();
}
#When("I add {string}")
public void i_add(String todoItem) {
addTodo.itemCalled(todoItem);
}
#Then("(?:.*) todo list should has followings:")
public void todo_list_should_has_followings(List<String> expectedItems) {
assertThat(todoItems.currentItems()).containsAll(expectedItems);
}
#And("the remaining item count is displayed as {string}")
public void remaining_item_count_displayed(String remainingItemCountText) {
assertThat(todoItems.numberOfItemsLeftMessage()).isEqualTo(remainingItemCountText);
}
#Given("I have a todo list containing")
public void has_a_list_containing(List<String> expectedItems) {
navigate.toTheTodoMVCApplication();
addTodo.itemsCalled(expectedItems);
}
#Steps
FilterItemsActions filterItems;
#When("I filter the list to show {word} tasks")
public void filtersBy(String filters) {
filterItems.by(filters);
}
#Steps
CompleteTodoActions completeTodo;
#When("I complete {string}")
public void complete(String completedTodo) {
completeTodo.itemCalled(completedTodo);
}
#Then("the todo item called {string} should be marked as completed")
public void theTodoItemCalledShouldBeMarkedAsCompleted(String todoItem) {
assertThat(completeTodo.isCompleted(todoItem)).isTrue();
}
}
the editor suggested me to use scenario outline. so i just go ahead and change it.
let me know what should be the correct structure, just using scenario good enough?
A scenario outline creates a separate scenario for each row in the examples column. I would suggest that as a new user to cucumber you avoid scenario outlines, there is no need for them and they just complicate things.
I'm a veteran Cuker (since before Cucumber was named). I don't ever use scenario outlines.
From your question it seems to me that what you are trying to do in this scenario is test filtering. A better scenario would make this clearer. How about
Feature: Filtering todo's
Scenario: View completed todo's
Given I have some todo's
And one todo is completed
When I view my todo's
And I filter on completed
Then I should see only my completed todo
Note: How I am not describing how to do anything. This is the preferred way to Cuke.
Related
I have to add a description field that is mandatory, so that the action of processing can be carried out, however I am a little confused, due to the fact that the field is in the filter area, to be copied later in the descriptions to be processed.
How can I customize the actions Process, ProcessAll?
I don't find these actions in Override Methods
thanks for helping me, I'm really new to this
sorry if my english is not so good
Basically, the Process/Process All actions are mapped to one method which is using the SetProcessDelegate method of the processing data view.
What you need to do is for first locating to the Graph(ProcessInputSVAT) of the Recognize Input VAT screen(TX503500). After opening the source code for that graph you can see that it's derived from the ProcessSVATBase class. And when you'll enter that class you'll see the mentioned SetProcessDelegate function called by Data View:
protected virtual void SVATTaxFilter_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
{
SVATTaxFilter filter = (SVATTaxFilter)e.Row;
if (filter == null)
{
return;
}
this.SVATDocuments.SetProcessDelegate(delegate(List<SVATConversionHistExt> list)
{
ProcessSVATBase.ProcessPendingVATProc(list, filter);
});
}
So we've figured out which graph extension we should create. Now, it's necessary to override the RowSelected event of the SVATTaxFilter DAC in the extension graph.
public class ProcessSVATBaseExt : PXGraphExtension<ProcessSVATBase>
{
public virtual void SVATTaxFilter_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
{
SVATTaxFilter filter = e.Row as SVATTaxFilter;
if (filter != null)
{
Base.SVATDocuments.SetProcessDelegate(delegate (List<SVATConversionHistExt> list)
{
// Here you can manage the list items and then call the base method
// ...
ProcessSVATBase.ProcessPendingVATProc(list, filter); // the base method
// Here you can manage the list items after the base method
// ...
});
}
}
}
I'm trying to display a warning every time the ShippedQty field is changed to a value < OrigOrderQty on the "Shipment - SO302000" screen, but I only want the code to be active for that specific screen/form.
I added the code below to extend the SOShipmentEntry graph, which accomplishes my original goal, but the issue is that now the code I added is also being used by the "Create Shipment" action in "Sales Orders - SO301000" screen/form.
Create Shipment Action Discussed
namespace PX.Objects.SO
{
public class SOShipmentEntry_Extension : PXGraphExtension<SOShipmentEntry>
{
#region Event Handlers
protected void SOShipLine_ShippedQty_FieldUpdated(PXCache cache,PXFieldUpdatedEventArgs e)
{
var myrow = (SOShipLine)e.Row;
if (myrow == null) return;
if (myrow.ShippedQty >= myrow.OrigOrderQty)
{
}
else
{
throw new PXSetPropertyException("The difference between the shipped-qty and the ordered-qty will be placed on a back-order", PXErrorLevel.Warning);
}
}
#endregion
}
}
While the warning allows the user to save changes to a shipment on the Shipment Screen/form SO302000 (Because the exception is set up as a warning and not an error), I get the following error when I create a shipment using the "Create Shipment" button on the "Sales Orders - SO301000" screen.
Warning works fine for form-mode
Warning becomes error when processed in background by action button
Any ideas to accomplish this? It is my understanding that if I want to make global changes to a field I must make them in the DAC, but if I want to make changes that only affect screens/forms where a graph is used, then I have to make those changes in the graph code itself. I'm guessing the "Create Shipment" action button in the Sales Orders screen is creating an instance of the graph where I added the code, so I'm wondering what are my options here.
Best regards,
-An Acumatica newbie
If you want your event logic to execute only when CreateShipment is invoked from the Shipment screen you can override the other calls to CreateShipment to dynamically remove your event handler.
The event that invokes CreateShipment action from the SalesOrderEntry graph is Action:
public PXAction<SOOrder> action;
[PXUIField(DisplayName = "Actions", MapEnableRights = PXCacheRights.Select)]
[PXButton]
protected virtual IEnumerable Action(PXAdapter adapter,
[PXInt]
[PXIntList(new int[] { 1, 2, 3, 4, 5 }, new string[] { "Create Shipment", "Apply Assignment Rules", "Create Invoice", "Post Invoice to IN", "Create Purchase Order" })]
int? actionID,
[PXDate]
DateTime? shipDate,
[PXSelector(typeof(INSite.siteCD))]
string siteCD,
[SOOperation.List]
string operation,
[PXString()]
string ActionName
)
In that method it creates a SOShipmentEntry graph to create the shipment. You can override Action and remove your handler from that graph instance:
SOShipmentEntry docgraph = PXGraph.CreateInstance<SOShipmentEntry>();
// >> Remove event handler
SOShipmentEntry_Extension docgraphExt = docgraph.GetExtension<SOShipmentEntry_Extension>();
docgraph.FieldUpdated.RemoveHandler<SOShipLine.shippedQuantity>(docgrapExt.SOShipLine_ShippedQty_FieldUpdated);
// << Remove event handler
docgraph.CreateShipment(order, SiteID, filter.ShipDate, adapter.MassProcess, operation, created);
Note that in order to reference SOShipLine_ShippedQty_FieldUpdated method from another graph you'll have to make it public:
public void SOShipLine_ShippedQty_FieldUpdated(PXCache cache,PXFieldUpdatedEventArgs e)
I have described how to do this in that answer too:
Updating custom field is ending into infinite loop
If you want your event logic to execute only when it is modified in the UI or by web service.
You can use the ExternalCall Boolean property of the PXFieldUpdatedEventArgs parameter.
This property value will be true only when the sender field is modified in the UI or by web service.
Usage example:
protected void SOShipLine_ShippedQty_FieldUpdated(PXCache cache,PXFieldUpdatedEventArgs e)
{
// If ShippedQty was updated in the UI or by a web service call
if (e.ExternalCall)
{
// The logic here won't be executed when CreateShipment is invoked
}
}
ExternalCall Property (PXFieldUpdatedEventArgs)
Gets the value specifying whether the new value of the current DAC field has been changed in the UI or through the Web Service API.
We're using the Run Project Billing screen to create records in AR / Invoice and Memo.
In the Invoice & Memo screen, we need the process to populate the header Customer Ord. number, along with a user field that has been added to the grid section on the 'Document Details' tab. At the moment, the process is not doing this.
I'd like to intercept the processing action on the screen using a technique I'm familiar with, namely using an 'AddHandler':
[PXOverride]
protected virtual IEnumerable Items (PXAdapter adapter)
{
PXGraph.InstanceCreated.AddHandler<BillingProcess>((graph) =>
{
graph.RowInserting.AddHandler<BillingProcess.ProjectsList>((sender, e) =>
{
//Custom logic goes here
});
});
return Base.action.Press(adapter);
}
I see no Base.Actions that remotely resembles 'Bill' or 'Bill All'.
This is obviously not exactly the code I need, but I would think this is the general place to start.
After reviewing the source business logic, I don't see any 'Bill' or 'Bill All' Actions - or any 'Actions' at all (baffling). I see an IEnumerable method called 'items', so that's what I started with above.
Is this the correct way to go about this?
Update: 2/14/2017
Using the answer provided re: the overridden method InsertTransaction(...) I've tried to set our ARTran user field (which is required) using the following logic:
PMProject pmproj = PXSelect<PMProject, Where<PMProject.contractID, Equal<Required<PMProject.contractID>>>>.Select(Base, tran.ProjectID);
if (pmproj == null) return;
PMProjectExt pmprojext = PXCache<PMProject>.GetExtension<PMProjectExt>(pmproj);
if (pmprojext == null) return;
ARTranExt tranext = PXCache<ARTran>.GetExtension<ARTranExt>(tran);
if (tranext == null) return;
tranext.UsrContractID = pmprojext.UsrContractID;
Even though this sets the user field to the correct value, it still gives me an error that the required field is empty when the process finishes. My limited knowledge prevents me from understanding why.
On the Run Project Billing screen, captions of Process and Process All buttons were changed to Bill and Bill All respectively in BLC constructor.
Process delegate is set for Items data view within the BillingFilter_RowSelected handler:
public class BillingProcess : PXGraph<BillingProcess>
{
...
public BillingProcess()
{
Items.SetProcessCaption(PM.Messages.ProcBill);
Items.SetProcessAllCaption(PM.Messages.ProcBillAll);
}
...
protected virtual void BillingFilter_RowSelected(PXCache cache, PXRowSelectedEventArgs e)
{
BillingFilter filter = Filter.Current;
Items.SetProcessDelegate<PMBillEngine>(
delegate (PMBillEngine engine, ProjectsList item)
{
if (!engine.Bill(item.ProjectID, filter.InvoiceDate, filter.InvFinPeriodID))
{
throw new PXSetPropertyException(Warnings.NothingToBill, PXErrorLevel.RowWarning);
}
});
}
...
}
As code snippet above confirms, all records in the AR Invoice and Memos screen are created by instance of the PMBillEngine class. Below is code snippet showing how to override InsertNewInvoiceDocument and InsertTransaction methods within the PMBillEngine BLC extension:
public class PMBillEngineExt : PXGraphExtension<PMBillEngine>
{
public delegate ARInvoice InsertNewInvoiceDocumentDel(string finPeriod, string docType, Customer customer,
PMProject project, DateTime billingDate, string docDesc);
[PXOverride]
public ARInvoice InsertNewInvoiceDocument(string finPeriod, string docType, Customer customer, PMProject project,
DateTime billingDate, string docDesc, InsertNewInvoiceDocumentDel del)
{
var result = del(finPeriod, docType, customer, project, billingDate, docDesc);
// custom logic goes here
return result;
}
[PXOverride]
public void InsertTransaction(ARTran tran, string subCD, string note, Guid[] files)
{
// the system will automatically invoke base method prior to the customized one
// custom logic goes here
}
}
Run Project Billing process invokes InsertNewInvoiceDocument method to create new record on the AR Invoice and Memos screen and InsertTransaction method to add new invoice transaction.
One important thing to mention: overridden InsertNewInvoiceDocument and InsertTransaction methods will be invoked when a user launches Run Project Billing operation either from the processing Run Project Billing screen or from the data entry Projects screen.
For more information on how to override virtual BLC methods, see Help -> Customization -> Customizing Business Logic -> Graph -> To Override a Virtual Method available in every Acumatica ERP 6.1 website
How do I add an action and handler to the Process Shipments screen? We want to add an action to the Action combobox on screen SO503000, and then add a handler in code to process the new action. We want to do this without having to override the huge switch/case statement for Action in the SOShipmentEntry graph.
The PXAutomationMenu attribute pulls from Automation Steps all actions, which have appropriate processing screen set up as Mass Processing Screen:
To extend the list of actions available on the Process Shipments screen, please proceed as follows:
Declare custom action within a BLC extension and invoke AddMenuAction method during BLC initialization to add it as a drop-down item for the Actions button
To add custom action to the Process Shipments screen, add custom actions to appropriate automation step(s) and specify Mass Processing Screen ID. When user selects your custom action, Shipments from all Automations Steps, that contain a custom action, will be available for selection on the Process Shipments screen:
Two extensions (of the same 1st level) declared for the SOShipmentEntry BLC, as shown in the code snippet below, can be used to extend Actions drop-down with multiple customization projects (two customization packages that are independent of each other; either one or both may be published on a particular site. And both add an action to the Process Shipments screen):
To address this scenario, :
public class SOShipmentEntryExt1 : PXGraphExtension<SOShipmentEntry>
{
public PXAction<SOShipment> Test1;
[PXButton]
[PXUIField(DisplayName = "Test Action 1")]
protected void test1()
{
throw new PXException("Not implemented action: {0}", "Test Action 1");
}
public override void Initialize()
{
Base.action.AddMenuAction(Test1);
}
}
public class SOShipmentEntryExt2 : PXGraphExtension<SOShipmentEntry>
{
public PXAction<SOShipment> Test2;
[PXButton]
[PXUIField(DisplayName = "Test Action 2")]
protected void test2()
{
throw new PXException("Not implemented action: {0}", "Test Action 2");
}
public override void Initialize()
{
Base.action.AddMenuAction(Test2);
}
}
I have following scenario outline
Background:
Given customer is in hot or not page
Scenario Outline: Hot article
And customer enters <name>
And submits
And customer clicks thumbs up
Then ensure the TBD
Examples:
| name |
| Elliot |
| Florian |
and following step implementation -
#And("customer enters <name>")
public void customer_enters_name(String name) throws Throwable {
// Express the Regexp above with the code you wish you had
Thread.sleep(10000);
}
But when I execute test then I get following error -
You can implement missing steps with the snippets below:
#Given("^customer enters Elliot$")
public void customer_enters_Elliot() throws Throwable {
// Express the Regexp above with the code you wish you had
throw new PendingException();
}
#Given("^customer enters Florian$")
public void customer_enters_Florian() throws Throwable {
// Express the Regexp above with the code you wish you had
throw new PendingException();
}
Did I implement test steps wrong?
Instead of
Scenario Outline: ...
And customer enters <name>
...
Do this (Note the double quotes)
Scenario Outline: ...
And customer enters "<name>"
...
Just to add, The same error arise when in the runner class ,we put the wrong package of the step class
#CucumberOptions(glue = {"com.wrongpackage.step"})
public class TestRunner{
}
Step class should be present and the package should be correct.