How to test RxJs4 streams containing promise chains - unit-testing

I'm having difficulty grasping how to swap out a promise chain from my Rx stream so I can test it.
The snippet below is from the documentation of RxJs createResolvedPromise and has been enhanced with a chained .then(()=>..) to better simulate my code. When running this example the .then() is not applied to the results emitted.
var scheduler = new Rx.TestScheduler();
// Create resolved promise
var xs = scheduler.createResolvedPromise(201, 'bar')
.then(val => 'foo:'+val);
// Note we'll start at 200 for subscribe, hence missing the 150 mark
var res = scheduler.startScheduler(
// fromPromise needs scheduler explicitly, see https://github.com/Reactive-Extensions/RxJS/issues/976
() => Rx.Observable.fromPromise(xs, scheduler)
);
// expected: value to be foo:bar but got bar
console.log(res.messages.map(msg => `msg:#${msg.time} val:${msg.value}`));
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/4.1.0/rx.all.js"></script>
It seems that the .then() is ignored when using the TestScheduler (although createResolvedPromise returns a Mock promise with implementation of .then to also return a MockPromise...).
The example above is heavily simplified, The real code would be something along:
const myStream = Rx.Observable.interval(100)
.flatMap(() => doPromiseOne().then(res => doPromiseTwo(res)))
.subscribe(console.log);
So what i am trying to attain in my test is that i can resolve promiseOne (using createResolvedPromise?) and let it flow through doPromiseTwo so i can observe the results.

Related

how to implement comparing two screenshots in one test with playwright

I am very new to playwright and i have a problem.
I am trying to implement comparing two screenshots (before and after) in one test.
this is what i want to achieve:
navigate to webpage
take screenshot (before.png)
do some stuff,state changes, etc
take screenshot (after.png)
compare before.png to after.png (if they are the same test should pass, otherwise test fails)
something like this:
test('compare screenshots', async ({ page }) => {
await page.goto('my website here');
const beforeImage = await page.screenshot({
path: `./screenshots/before.png`
})
//
// some state changes implemented here
//
const afterImage = await page.screenshot({
path: `./screenshots/after.png`
})
expect(beforeImage).toMatchSnapshot(afterImage)
});
but it does not work like this.
Any ideas/suggestions how can i achieve this?
Help would be greatly appreciated
You can do something like this:
test('compare screenshots', async ({ page }, testInfo)=>{
await page.goto(pageUrl);
const screenshotTarget = page.locator(scTarget);
await expect(screenshotTarget).toHaveScreenshot( `${testInfo.title}.png`);
//
// some state changes implemented here
//
await expect(screenshotTarget).toHaveScreenshot( `${testInfo.title}.png`);
});
I prefer to use the test titel for naming my screenshots but it should also work if you just enter the same name twice. Then if you run your tests without --update-snapshots they should fail if some visual changes happened.
The problem with Playwright's toHaveScreenshot and toMatchSnapshot is that they're a bit over-engineered and will only compare a current screenshot to a screenshot from a previous test run. If you want to compare two screenshots that you have as Buffers in memory, you can use the getComparator method that Playwright uses behind the scenes:
import { getComparator } from 'playwright-core/lib/utils';
await page.goto('my website here');
const beforeImage = await page.screenshot({
path: `./screenshots/before.png`
});
//
// some state changes implemented here
//
const afterImage = await page.screenshot({
path: `./screenshots/after.png`
});
const comparator = getComparator('image/png');
expect(comparator(beforeImage, afterImage)).toBeNull();
The advantage of using getComparator is that it fuzzy matches, and you can set the threshold of how many pixels are allowed to be different. If you just want to check that the PNGs are exactly identical, a dead simple method to check for equality between the two screenshots is:
expect(Buffer.compare(beforeImage, afterImage)).toEqual(0)
Beware though - this simpler method is flakey and sensitive to a single pixel difference in rendering (such as if any animations/transitions are not completed or if there are differences in anti-aliasing).

Create TestProbe of an child actor from a name

Using akka typed: 2.6.10. My parent generates child actors to do some work as you can see below (note this is part of event sourced actor). Is there a way to acquire reference to internally created child actor using possibly name during testing time?
For example, below we have child actor provider_1 which is created at initialization time and I am hoping to acquire a reference to TestProbe using this name from outside. I am reluctant to change the way code is structured for sake of testing, for example in here there are some reference to passing in ref/factory or re-constructing parent in test in order to test this, which I would like to avoid.
def commandHandler(
ctx: ActorContext[Command]
): (State, Command) => Effect[Event, State] = { (state, cmd) =>
cmd match {
case Init =>
ctx.spawn(Provider(ctx.self), "provider_1")
Effect.none
}
}
If you're using the BehaviorTestKit to test the actor, the actor gets run with an alternative ActorContext implementation.
So the following should work (note that akka.actor.testkit.typed.Effect has little relation to Effect in persistence), using scalatest matchers:
import akka.actor.testkit.typed.Effect.Spawned
val testKit = BehaviorTestKit(behaviorUnderTest)
testKit.run(Init)
val effect = testKit.retrieveEffect : akka.actor.testkit.typed.Effect
val childActorRef =
effect match {
case s: Spawned if s.childName == "provider_1" => s.ref
case _ => fail()
}
val childInbox = testKit.childInbox(childActorRef)
testKit.run(SendMessageToYourChild("hello"))
childInbox.hasMessages shouldBe true
childInbox.receiveMessage shouldBe MessageFromParent("hello")
akka.actor.testkit.typed.scaladsl.TestInbox is intended to be the synchronous behavior testing analogue to the asynchronous TestProbe.
I'm not aware of an analogous method for the asynchronous ActorTestKit, where a child actor will actually be spawned.

Compare two values and make decision in Cypress

So I have two values on a page that I need to compare and as per the result perform some actions.
//First Block
cy.get('selctor1').invoke('text').then(somevalue => {
cy.get('selector2').should('have.text', somevalue).then(() => {
#Do Something when equal
})
})
//Second Block
cy.get('selctor1').invoke('text').then(somevalue => {
cy.get('selector2').should('not.have.text', somevalue).then(() => {
#Do Something when not equal
})
})
So for the positive case when both values are equal everything works fine. But for the case when two values are not equal, it's only checking the first block and fails. What should I do so that it executes the second block when values are not equal and not the first block?
Sorry for not being clear the first time. Here is my edited answer:
Then vs Should:
Try to avoid then where possible. then is not repeatable and will introduce unexpected behaviour.
But also will should introduce unexpeced behaviour.
Example for a bad usage of then:
describe("asd", () => {
it("fails but retries", () =>{
console.log("######### first test")
cy.wrap({ fn: () => console.log(new Date())})
.invoke("fn")
.should(r => expect(r).to.eq(true));
})
it("fails but retries not", () =>{
console.log("######### next test")
cy.wrap({ fn: () => console.log(new Date())})
.invoke("fn")
.then(r => {
expect(r).to.eq(true)
});
})
})
In this example you see the same code twice but the first block uses should while the second block uses then. The assertion must fail but in the first block, the assertion is repeated. Open the DEV COnsole to see many retries for the first block but no retry in the second.
This is what I mean by "unexpected" behaviour. Let's say, you wrap a object that is dynamically extended (maybe by a UI action) and you are expecting a property on this object. In the second block (then) the UI acton must be executed very fast and before thethenis executed so that theexpect` does not fail.
In the should case, you have 4 seconds (in case of `defaultCommandTimeout is not overwritten) left until the assert will finally fail.
Bad usage of should:
describe("ad", () => {
it("test", () => {
cy.visit("https://www.cypress.io/")
cy.get("*[aria-label='pricing']")
.invoke('text').should(someValue => {
cy.get("asdad", {timeout: 5000}).should("not.exist");
})
})
})
What would you expect? A green test? No, this test fails:
Why is this the case? Because get introduces an implicit assert "should exist" (see: https://docs.cypress.io/guides/core-concepts/introduction-to-cypress.html#Default-Assertions ).
Should with callback skips the default assertion (see: https://docs.cypress.io/api/commands/should.html#Notes ).I think they skip it by toggling it by flag. This could have the effect of reversing the flag again and thus forces cypress to check if "asdad" does exist even though we use should not exist.
There is an issue for this stuff: https://github.com/cypress-io/cypress/issues/5963
I do not know why cy.log has the behaviour you mentioned in your case. So either you use then if you want to use cy commands within then callback or you avoid the usage of cy commands and use should with explicit assertions (expect). Maybe after that issue is fixed, cy.log also can be used.
Old Answer:
cy.get('selctor1').invoke('text').should(someValue => {
const $el = Cypress.$('selector2');
if ($el.text() ==== someValue) {
// positive
expect()....
} else {
// negative
expect()....
}
})
You can use should with a callback. This callback (and the previous invoke command) is executed as long as the timeout is reached or no assertion fails.
You always can use the raw jQuery object to work with. This depends on whether or not you need all the checks cypress is executing during a get().
Please let me know if you need further assistance.

How to await for the stream event to get processed in the unit-test?

The unit-test implies that after some item was passed to a Sink object through the add method, than some operation will be performed in response to it.
class Subject {
final StreamController<Item> _itemStreamController = StreamController();
Sink<Item> get itemsSink => _itemStreamController.sink;
Stream<Item> get _itemsStream => _itemStreamController.sink;
final SomeService _service;
Subject(this._service) {
_itemsStream.listen((item) => _service.processItem(item));
}
}
And the unit test itself:
test('description', () async {
final Item givenItem = Item("givenValue");
final SomeService givenService = MockSomeService();
final Subject subject = Subject(givenService);
subject.itemsSink.add(givenItem);
verify(givenService.add(givenItem));
});
And as you can understand the event looping thread firstly processes verify instructions and only then dispatches the event to the listener.
If I just insert await Future.value(null); between sink interaction and method invocation verification than all works like a charm. Still, this solution is quite ugly.
Does the unit-testing framework itself offer something to schedule verification at the end of event loop? Or any measures to get this unit-test passed without resorting to something like await Future.value(null);?

Play 2.1: unit testing EssentialActions

I want to unit test a controller method that returns an EssentialAction. I pass a FakeRequest to it, and get back a Iteratee[Array[Byte], Result].
It looks like the test helpers contentAsString, contentType and status do not accept this result type.
Is there an implicit conversion I am missing? Is there an example somewhere of controllers being unit tested without bringing up an entire FakeApplication?
An essential action is a RequestHeader => Iteratee[Indata, Result], you can apply it to FakeRequest since it implements RequestHeader. To actually execute the iteratee you either stuff it with data or just tell it right away that there is no more indata. For both those cases you get a Future[Result] back which you need to wait for in the tests.
So, for a simple GET with no request body (using the play test helper await method) you could do it like this:
val iteratee = controllers.SomeController.action()(FakeRequest())
val result: Result = await(iteratee.run)
If you want to do requests with request bodies you will have to do some more stuff to be able to feed the request body to the iteratee and also take care of encoding data your indata correctly.
In Play 2.3, PlaySpecification includes a couple of helper methods. In order to handle EssentialActions, you'd use call. The resulting future is handled by other more specific helpers.
class MySpec extends PlaySpecification {
...
val result1: Result = call(controllers.SomeController.action(), FakeRequest(...))
status(of = result1) must equalTo (OK)
...
val result2 = call(controllers.SomeController.action(), RequestHeader(...), "Body")
status(of = result2) must equalTo (BAD_REQUEST)
}