if-else conditions based on expect statement results - webdriver

I'm working towards testrail integrations, i want to update testrail after each test pass/fail. Lets day if i've a test like below
it('rightpanel should exist', () => {
//some logic or preparatory work
expect(rightpanel.isLoaded()).to.be.true;
// here i want to know whether above expect statement failed or passed.
// based on it, i want to update test rail by making a webservice call
});
we are using WDIO, is there a better way to integrate to testrail? No one replies on their community forum so, i'm asking here.

With mocha you can use a repoter to manage the results of your tests.
The default reporter is Spec, but if you use json-stream you can attach another process to this stream to send test reports to testrail while executing.
Otherwise, if you don't need to send them in real time, you can use the json reporter and parse them in a single call.
You can also check on github some existing reporter that connects directly to testrail:
https://github.com/CommodoreBeard/mocha-testrail-advanced-reporter
https://github.com/awaragi/mocha-testrail-reporter
complete list

Related

Is there any way to get the c# object/data on which NUnit test is failing?

I am writing unit tests for a complex application which has so many rules to be checked into a single flow by using NUnit and Playwright in .Net5. Actually the case is, to save the time for writing the test scripts for Playwright (front-end testing tool), we have used a library named Bogus to create dummy data dynamically based on the rules (because the test cases has numerous rules to be checked and it was much more difficult to write fresh data to every case). I am using Playwright script into the NUnit test and providing the data source by using [TestCaseSource("MethodName")] to provide dynamic data object for different cases.
Now, we are facing a problem that some of the tests cases get passed and some are failed and we are unable to identify that particularly which test case is causing the problem because the testcase data is being provided by the dynamic source and in that source the data is being generated by the Bogus library on the bases of the rules which we have generated. Plus, we cannot look at the tests for a long time that's why we have automated the process.
[Test]
[TestCaseSource("GetDataToSubmit")]
public async Task Test_SubmitAssignmentDynamicFlow(Assignment assignment)
{
using var playwright = await Playwright.CreateAsync();
await using var browser = await playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions
{
Headless = false,
...
});
....
private static IEnumerable<TestCaseData> GetDataToSubmit()
{
//creating data for simple job
var simpleAssignment = new DummyAssigmentGenerator()
....
.Generate();
yield return new TestCaseData(simpleAssignment);
....
Now, my question is, is there any way so that we can view that what were the actual values in the object in the failed case, when we see the whole report of the testcases? So that we can come to know that which certain values are causing problems and eventually fixed those.
Two approaches...
Assuming that DummyAssignmentGenerator is your own class, override its ToString() method to display whatever you would like to see. That string will become part of the name of the test case generated, like...
Test_SubmitAssignmentDynamicFlow(YOUR_STRING)
Apply a name to each TestCaseData item you yield using the SetName() fluent method. In that case, you are supplying the full display name of the test case, not just the part in parentheses. Use {m}(YOUR_STRING) in order to have it appear the same as in the first approach.
If you can use it, the first approach is clearly the simpler of the two.

Wanting to chain web requests and pass data down through them in Twilio Studio

So I'm playing with Twilio Studio, and building a sample IVR. I have it doing a web request to an API that looks up the customer based on their phone number. That works, I can get/say their name to them.
I'm having trouble with the next step, I want to do another http request and pass the 'customer_id' that I get in webrequest1 to webrequest2, but it almost looks like all the web requests fire right when the call starts instead of in order/serialized.
It looks sorta like this;
call comes in, make http request to lookup customer (i get their customer_id and name)
split on content, if customer name is present, (it is, it goes down this decision path)
do another http request to "get_open_invoice_count", this request needs the customer_id though and not their phone number.
From looking at the logs it's always got a blank value there, even though in the "Say" step just above I can say their customer_id and name.
I can almost imagine someone is going to say I should go use a function, but for some reason I can't get a simple function to do a (got) get request.
I've tried to copy/paste this into a function and I kind of think this example is incomplete: https://support.twilio.com/hc/en-us/articles/115007737928-Getting-Started-with-Twilio-Functions-Beta-
var got = require('got');
got('https://swapi.co/api/people/?search=r2', {json: true})
.then(function(response) {
console.log(response)
twiml.message(response.body.results[0].url)
callback(null, twiml);
})
.catch(function(error) {
callback(error)
})
If this is the right way to do it, I'd love to see one of these ^ examples that returns json that can be used in the rest of the flow. Am I missing something about the execution model? I'm hoping it executes step by step as people flow through the studio, but I'm wondering if it executes the whole thing at boot?
Maybe another way to ask this question is; If I wanted to have the IVR be like
- If I know who you are, i send you down this path, if I know who you are I want to lookup some account details and say them to you and give you difference choices than if you are a stranger.
---- how do you do this?
You're right -- that code excerpt from the docs is just a portion that demonstrates how you might use the got package.
That same usage in context of the complete Twilio Serverless Function could look something like this:
exports.handler = function(context, event, callback) {
var twiml = new Twilio.twiml.MessagingResponse();
var got = require('got');
got('https://example.com/api/people/?search=r2', { json: true })
.then(function(response) {
console.log(response);
twiml.message(response.body.results[0].url);
callback(null, twiml);
})
.catch(function(error) {
callback(error);
});
};
However, another part of the issue here is that the advice in this documentation is perfectly reasonable for Functions when building an app on the Twilio Runtime, but there are a couple of unsaid caveats when invoking these functions from a Studio Flow context. Here's some relevant docs about that: https://support.twilio.com/hc/en-us/articles/360019580493-Using-Twilio-Functions-to-Enhance-Studio-Voice-Calls-with-Custom-TwiML
This function would be acceptable if you were calling it directly from an inbound number, but when you use the Function widget within a Studio flow to return TwiML, Studio releases control of the call.
If you want to call external logic that returns TwiML from a flow, and want to return to that flow later, you need to use the TwiML Redirect widget (see "Returning control to Studio" for details).
However, you don't have to return TwiML to Studio when calling external logic! It sounds like you want to make an external call to get some information, and then have your Flow direct the call down one path or another, based on that information. When using a Runtime Function, just have the function return an object instead of twiml, and then you can access that object's properties within your flow as liquid variables, like {{widgets.MY_WIDGET_NAME.parsed.PROPERTY_NAME}}. See the docs for the Run Function widget for more info. You would then use a "Split Based On..." widget following the function in your flow to direct the call down the desired branch.
The one other thing to mention here is the Make HTTP Request widget. If your Runtime Function is just wrapping a call to another web service, you might be able to get away with just using the widget to call that service directly. This works best when the service is under your control, since then you can ensure that the returned data is in a format that is usable to the widget.

How can I run a task inside a meteor method without waiting for it to complete?

I have several function calls in a row that run and wait to return, then the next one runs. After these are run I have one function I want to run, but then I don't want to wait for it to be done before I run my return.
Here is an example of what I mean.
get_card, create_order, create_association and debit_order all need to wait for the previous function to complete before they can run. When I get to Queue.start_account_creation_task I want it to start running, but then let the return on the line below run right away too.
Meteor.methods({
singleDonation: function (data) {
logger.info("Started singleDonation");
//Get the card data from balanced and store it
var card = Utils.get_card(customerData._id, data.paymentInformation.href);
//Create a new order
var orders = Utils.create_order(data._id, customerData.href);
//Associate the card with the balanced customer
var associate = Utils.create_association(customerData._id, card.href, customerData.href);
//Debit the order
var debitOrder = Utils.debit_order(data.paymentInformation.total_amount, data._id, customerData._id, orders.href, card.href);
Queue.start_account_creation_task(customerData._id, data._id, debitOrder._id);
return {c: customerData._id, don: data._id, deb: debitOrder._id};
}
});
Sounds like you need parallel and serial control for tasks. The (as in, 400,000 downloads a day) Node.js module for that is called async, and a Meteor wrapper for it is peerlibrary:async.
Sooner or later you'll need a dedicated background task management package. If async is insufficient, have a look at my evaluation of packages to control background tasks in Meteor.
The thing that seemed to work the best for what I was trying to do was to just use a Meteor.setTimeout({}). It might seem like an odd choice, but it does everything I needed, including setting the Meteor Environment so that I didn't have to do any BindEnrironment call. It also breaks out of the current thread of calls, which means it then returns the result to the client and a second later finishes the rest of the calls (which are to external APIs that I didn't need my users sitting there waiting for).

Update document in Meteor mini-mongo without updating server collections

In Meteor, I got a collection that the client subscribes to. In some cases, instead of publishing the documents that exists in the collection on the server, I want to send down some bogus data. Now that's fine using the this.added function in the publish.
My problem is that I want to treat the bogus doc as if it were a real document, specifically this gets troublesome when I want to update it. For the real docs I run a RealDocs.update but when doing that on the bogus doc it fails since there is no representation of it on the server (and I'd like to keep it that way).
A collection API that allowed me to pass something like local = true this would be fantastic but I have no idea how difficult that would be to implement and I'm not to fond of modifying the core code.
Right now I'm stuck at either creating a BogusDocs = new Meteor.Collection(null) but that makes populating the Collection more difficult since I have to either hard code fixtures in the client code or use a method to get the data from the server and I have to make sure I call BogusDocs.update instead of RealDocs.update as soon as I'm dealing with bogus data.
Maybe I could actually insert the data on the server and make sure it's removed later, but the data really has nothing to do with the server side collection so I'd rather avoid that.
Any thoughts on how to approach this problem?
After some further investigation (the evented mind site) it turns out that one can modify the local collection without making calls to the server. This is done by running the same methods as you usually would, but on MyCollection._collection instead of just on Collection. MyCollection.update() would thus become MyCollection._collection.update(). So, using a simple wrapper one can pass in the usual arguments to a update call to update the collection as usual (which will try to call the server which in turn will trigger your allow/deny rules) or we can add 'local' as the last argument to only perform the update in the client collection. Something like this should do it.
DocsUpdateWrapper = function() {
var lastIndex = arguments.length -1;
if (arguments[lastIndex] === 'local') {
Docs._collection.update(arguments.slice(0, lastIndex);
} else {
Docs.update(arguments)
}
}
(This could of course be extended to a DocsWrapper that allows for insertion and removals too.)(Didnt try this function yet but it should serve well as an example.)
The biggest benefit of this is imo that we can use the exact same calls to retrieve documents from the local collection, regardless of if they are local or living on the server too. By adding a simple boolean to the doc we can keep track of which documents are only local and which are not (An improved DocsWrapper could check for that bool so we could even omit passing the 'local' argument.) so we know how to update them.
There are some people working on local storage in the browser
https://github.com/awwx/meteor-browser-store
You might be able to adapt some of their ideas to provide "fake" documents.
I would use the transform feature on the collection to make an object that knows what to do with itself (on client). Give it the corruct update method (real/bogus), then call .update rather than a general one.
You can put the code from this.added into the transform process.
You can also set up a local minimongo collection. Insert on callback
#FoundAgents = new Meteor.Collection(null, Agent.transformData )
FoundAgents.remove({})
Meteor.call 'Get_agentsCloseToOffer', me, ping, (err, data) ->
if err
console.log JSON.stringify err,null,2
else
_.each data, (item) ->
FoundAgents.insert item
Maybe this interesting for you as well, I created two examples with native Meteor Local Collections at meteorpad. The first pad shows an example with plain reactive recordset: Sample_Publish_to_Local-Collection. The second will use the collection .observe method to listen to data: Collection.observe().

Unittesting a Save function using MVP pattern and RhinoMock

I am trying to get a better code coverage with my unittests, and recently I switched to using RhinoMock for my Mocking needs.
But I have got a question with how to write a specific unit-test, the Save() function.
I have an IView interface with several functions to retrieve values from the view (aspx page), examples are GetUsername(), GetPassword(), GetAddress() and GetCountry().
When the user clicks the submit button I want to have tests that tests if all these functions are actually being called. So I wrote this test:
[TestMethod]
public void MainController_Save_ShouldRetrieveLUsername()
{
//Initialize the IView and Controller
InitViewAndController();
//Trigger the Save function triggering the controller
//to collect information for storage
_controller.Save();
_view.AssertWasCalled(s => s.GetUsername(), o => o.Repeat.Once());
}
Now finally comes the question, considering the aspx contains 15 input fields that needs to be saved, is there a better way to test this behaviour that writing and maintaining 15 of these tests?
On one hand test should be simple and optimally only one Assert, but 15 of these functions feels like a waste.
Instead of testing whether these functions are called (they look more like properties instead of functions, BTW), you should check the results of the Save function. You should treat your test code more like a black box and try not to insert too much of its interior knowledge into your tests. This way your tests will be less brittle when the Save code changes.
Google for "state based testing".

Resources