Ensure one thing, and then another one if first is false - serenity-js

I have an interface with a list of users and a possibility to add a new one. I want to assert that this user is new (i.e. its email is not already used). So I should check that we have no message pop-up.
checkMailIsNotUsed: () =>
Task.where('#actor checks mail present message is absent',
Ensure.that(UsersList.messageArea, not(isVisible()))),
However this message area could be visible but not with the error messsage I don't expect. So I am looking for, in case above ensure fails, a way to ensure that the text does not include 'already exists'.
Ensure.that(Text.of(UsersList.messageArea), includes('already exists'))),
However if the first 'ensure' is false, everything stops. There is no 'or' or equivalent at the Ensure level. I need to do the second Ensure if first one fails.
How could I do that ?
Thanks in advance.

Related

Way to get messages from previous flows in a linear chain

I recently had a scenario like below:
Flow_A ------> Flow_B ------> Flow_C ------> Flow_D
Where
Flow_A is the initiator and should pass messageA.
Flow_B should pass messageA+messageB.
Flow_C should pass messageA+messageB+messageC
Flow_D should pass messageA+messageB+messageC+messageD.
So, I was thinking to enhance the headers with an old message and again pass to another flow. But, it will be very bulky at the end.
Should I store the message somewhere and then pass the messageId in the header, so that the next flow can get the old message with the messageId?
What should be the best way to achieve this?
See Claim Check pattern: https://docs.spring.io/spring-integration/docs/current/reference/html/message-transformation.html#claim-check
You store a message using ClaimCheckInTransformer and get its id as an output payload.
You move this id into a header and produce the next message.
Repeat #1 and #2 steps for this second message to be ready for the third one.
And so on to prepare environment for the fourth message.
To restore those messages you need to repeat the procedure opposite direction.
Get a header from the message into a payload, remove it and call ClaimCheckOutTransformer to restore a stored message. I say "remove header" to let the stack to be restored properly: the ClaimCheckOutTransformer has a logic like this:
AbstractIntegrationMessageBuilder<?> responseBuilder = getMessageBuilderFactory().fromMessage(retrievedMessage);
// headers on the 'current' message take precedence
responseBuilder.copyHeaders(message.getHeaders());
So, without removing that header, the same message id is going to be carried into the next step and you will be is a loop - StackOverflowError.
Another is to store messages manually somewhere, e.g. MetadataStore and collect their ids in the list for payload. This way you don't need extra logic to deal with headers. Everything in a list of your payload. You can consult the store any time for any id item in that list!

mail-listener2 - How to prevent function from reading wrong emails?

In my E2E test, I'am using the mail-listener2 to retrieve e-mails. It works fine, except one issue which is driving me crazy and just can't solve it... I have been searching and found different topics and issues regarding this library/package, but just couldn't really find the fix for that.
Following:
I use the function in more than one spec file (register, login, confirmation etc.), and this means that when retrieving the emails, I get from time to time the wrong one. In other words, the function reads the last e-mail in the Inbox which normally belongs to the first test.
Or sometimes the e-mail comes in the Inbox a little bit later that the function is reading them, so it reads the wrong one.
And as I do have an expectation in my it() function:
expect(email.subject).toEqual("subject for e-mail 1");
expect(email['headers'].to).toEqual( userEmail );
therefore the test breaks, and it get following error:
- Expected 'user registration' to equal 'user confirmation'.
- Failed: Cannot read property '1' of null
- Expected 'john.doe#foo.de' to equal 'jane.doe#foo.com'.
- Failed: Cannot read property '1' of null
Is there a way how to force the function reads just the specific email per subject and per user?
Yes, you can find this documented on node-imap (which is used by mail-listener2). Search for the paragraph/bullet on search within that package, here's a snippet to help you find it:
For criteria types that require arguments, use an array instead of just the string criteria type name (e.g. ['FROM', 'foo#bar.com']).
Below that, they list several other search criteria you can use, they have to/from for your user criteria, and subject for that one. So applying this to mail-listener2, you would use this in the searchFilter property:
mailListener = new MailListener({
...(other options),
searchFilter: [['FROM', 'automated#message.com'], ['SUBJECT', 'subject for e-mail 1']],
});
And if you need different search criteria for different tests, you can start a new mail-listener session for each test with the new searchFilter criteria.

Gamemaker variable using porals

I am remaking portal in gamemaker for my semester final, I was wondering how you find an object, if I have one portal down, and go into it, the game crashes, as the 2nd portal isn't placed, and it can't get its .x,.y pos. How do I set a variable to fix this?
We don't know how you determine the destination teleporter, you should clarify that. But one variant could be to check whether the amount of portals is >= 2, so you have at least one place to go
if (instance_number(your_portal_name) >= 2)
{
// proceed the portal mechanics
}
I assume that in some event you have a piece of code that does the teleporting. You just have to place this piece of code in an "if" statement that verifies if the second portal exists. This way, you will attempt teleportation only if the needed exit instance exists. You can use the "instance_exists" function
for example :
if ( instance_exists( exit_portal_or_whatever_you_name_it ) )
{
your_teleportation_code;
}
I would say that based on the information you gave us, German Gorodnev's answer is correct. If you only have one portal and you try to get the position of a non-existent portal, then you will get an error. So you should include an if statement that makes sure the needed portals are there before retrieving the positions.

Cucumber "OR" clause?

Is it possible to specify some kind of "OR" (alternative) clause in Cucumber?
I.e. if I have two valid responses to some event I would like my test to pass if either of them happens.
Something like that:
"When I press a button"
"Then I should see the text 'Boo'"
"Or I should see the text 'Foo'"
My particular scenario is a login screen. When I try to log in with some random password, I should see an error message "invalid password" if the server is working or a message "network error" if it is not.
You can't really define OR functionality using the Gherkin but you can pass in a list and check that one of the values in the list matches what was returned.
Define list:
Then the greeting service response will contain one of the following messages
|Hello how are you doing?|
|Welcome to the front door!|
|How has your day been?|
|Come right on in!|
Check list:
#Then("the get messages service response will contain one of the following messages")
public void text_matching_one_of_the_following(List<String> greetingMessages){
boolean success = false;
for(String message : greetingMessages){
assertTrue(textMatchesResponse(message));
}
}
OR is not supported. You can use Given, When, Then, And and But. Please refer to http://docs.behat.org/en/v2.5/guides/1.gherkin.html
But perhaps you could make use of the But keyword to achieve what you are looking for.

How to remove the data after user has logged out?

I was following along the example Lending Library app in the book "Packtpub.Getting.Started.with.Meteor.js". It is running at:
http://matloob.lendlib.meteor.com
It works fine, but when a user logs out when one category is open and its items are being displayed, that category and its items remain on the page while the rest is filtered out. On refreshing the page the remaining category is also filtered out.
The publish function is:
Meteor.publish("Categories", function () {
Meteor.flush(); // I added this so it will flush out the remaining data, but :(
return lists.find({owner: this.userId}, {fields: {Category: 1}});
});
It is hard to point out the exact vulnerability withour seeing more code but this is what I could find out: even if not logged in as a user one can set the session variable current_list to an id to get the corresponding list document:
Session.set("current_list",'ZLREaTCPiC6E7ece3')
So I assume that somewhere in your code you publish the details of a list given its id.
At least this would explain why the list remains even after logging out when a category is selected (which in turn means current_list holds an id).
Possibly publishing the list is done using Deps.autorun since the list is immediately published once the session variable is changed.
Maybe you can find that piece of code and post it or just change it so that it also includes a check whether the user is the owner of that list or category.
Consider using the user-status package to listen for users logging out and doing some cleanup on the server as a result:
https://github.com/mizzao/meteor-user-status
Specfically, you can use the following callback:
UserStatus.on "sessionLogout", (advice) ->
console.log(advice.userId + " with session " + advice.sessionId + " logged out")

Resources