To chain or not to chain?

Do you know you can use chains in Cypress?

1 Like

I’m going to start by showing people why I always had very few friends in school and was always picked last for anything.

That’s not really chaining" @restertest . ActionChains ala W3C protocol are what I would really call chaining. ActionChains are probably more like SQL scriptlets that are executed when you send the ‘GO’ keyword. These are more performant than any negligible difference between coding up:

object=driver.actionX()
object=object.actionY()
object= object.actionZ()

versus

driver.actionX().actionY().actionZ()

And although people may argue that the 1st example is easier to debug as well as easier to read, when you boil it all down in practise, debugging the prior is not any easier, and reading it actually is moderately evil when you happen to write this kind of code later on in a more non-trivial example.

object1=driver1.actionX()
object1=driver1.actionY()
object2=driver2.actionX()
object2=driver2.actionY()
object1=object1.actionZ()

because the cascading version suddenly starts to look a whole lot easier to read

object1 = driver1.actionX().actionY()
object2 = driver2.actionX().actionY()
object1 = object1.actionZ()

I’m using python language here, but any language will do. Where the performance differences between these 2 are negligible since the python language is one of many where there is never a “new” variable storage created, the interpreter is merely updating variable references as it goes and variable references are in local memory and are damn fast hash-table lookups. Every method call is an LPC (local procedure call) which turns into an IPC (inter procedure call) to the web server, that’s where the huge overhead comes in, and to boot the reason that updating to selenium 4 and using W3C drivers is the real performance win that using a stack like Cypress maintains will make sense.

One way to improve performance for example is to not assign the lvalue , at the end, which saves the interpreter maintaining a reference (a compiler might even choose to elide the return statement) but most test languages are not compiled, and eliding pushing to stack or tracking registers for the return, saves you only CPU cycles, while the reference tracking of that lvalue has a garbage collector impact, and you want that garbage collector to do less if you can.

I am a fan of the ‘chaining’ or cascading, but the jury is still out (in my mind) on what we should call this. I like to call it cascading, and especially becomes a very beautiful way to code when you are using page objects for example. I almost want to call it ‘flow’ style, because object state “flows” from right to left. But even that can be jarring for some people and that’s why we don’t see it very often as you really have to read from right to left… perhaps right-to-left is a way to describe it ? maybe not. What does the community want to call this style?

driver.actionX().actionY().actionZ()

2 Likes

But yes, thank you for bringing up this topic, I hope people can vote on a good name for the style you describe. I’m not a java patterns guru , and I had hoped the Java Patterns book would help us out here but this is a coding style not a pattern really. And as someone who was once a C/C++ language lawyer style matters a lot to me, but it’s only really a style when it is portable and when it is recognisable as a helpful way of add whitespace and structure as well as clarity of purpose.