Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

State of 2.0? #318

Closed
ctaepper opened this issue May 23, 2019 · 25 comments
Closed

State of 2.0? #318

ctaepper opened this issue May 23, 2019 · 25 comments

Comments

@ctaepper
Copy link

Hi Jan, I'm a big fan of your work ever since we started using serenity-js over a year ago.

First of all, sorry for opening an issue here, but I don't know how else I can get in touch with you...

I'm with a new company starting a new project and I definitely want to use serenity for our e2e needs. I can see v2 is under heavy development and you do regular alpha releases. Now I am wondering if it still makes sense using the current serenity version when starting a new project, meaning will v2 be an "easy" upgrade path or is it a larger rewrite and we should wait for v2 being released and even more important: documented

@jan-molak
Copy link
Member

jan-molak commented May 27, 2019

Hi @ctaepper! Thanks for your kind words and your support for Serenity/JS :-)

I'm finishing the last major feature for v2 now, which is adding support for the Jasmine framework. After that, the last thing that's left is to update the handbook and the tutorials - I think we're looking at a release date at some point in June.

Most classes already have comprehensive JSDoc with usage examples and those that don't will get it over the coming weeks, there are also several example mini-projects that demonstrate the major features.

I've designed v2 so that the upgrade path should be relatively straight-forward as the main classes (Actor, Task, Interaction and Question) are backwards compatible.

Having said that, if you're starting a new project now I'd suggest to either go with the alpha, which is now stable and any changes are limited to the internals, or wait for the "official release".

What I can also propose is that if you (or others) would like to experiment with v2 you could use this ticket to ask any questions about the new version or let me know if there are things we should address before the official realease.

@jan-molak jan-molak pinned this issue May 27, 2019
@asnov
Copy link
Contributor

asnov commented Jun 1, 2019

@jan-molak,
I tried to migrate some of my old tests to v2 and I didn't find photographer stage crew. What happened to him?
What can I use instead?

@jan-molak
Copy link
Member

jan-molak commented Jun 11, 2019

@asnov - Since Photographer is Protractor-specific, he decided to move to the @serenity-js/protractor module (specs available here).

import { Photographer, TakePhotosOfFailures } from '@serenity-js/protractor';

new Photographer(new TakePhotosOfFailures())

Which reminds me that I should:

  • add a factory method to make the instantiation simpler, maybe something like Photographer.whoWill(TakesPhotosOfFailures) 🤔 edit - done in 2.0.1-alpha.77
  • document that the Photographer has moved elsewhere. Maybe a migration guide could be useful?

@owlran
Copy link

owlran commented Jun 19, 2019

hi @jan-molak,

is any v2 document available ?

@jan-molak
Copy link
Member

Hi @owlran - the website hasn't been published yet as it would replace the existing one for version 1.
If you'd like to see a preview of the website for v2 you can clone this repository, checkout the 2.0 branch and run make clean site which generates the website under documentation/website/target.

@Ijee
Copy link

Ijee commented Jul 16, 2019

Hey,
I tried updating one of my projects to the new version but I am running into a few issues which you might be able to help me with:

  • I can not find the Is class - do I have to implement that myself using protractor or is it somewhere else?
  • I can not find the TakeNotes ability. Do you plan on adding it back?
  • @step('') for performAs for my custom tasks is not available anymore? It doesn't say anything about removing it in the changelog.
    Edit:
  • I also found that Check.whether(condition: boolean | Question<boolean> | Question<PromiseLike<boolean>>) {...} got changed to
    Check.whether<A>(actual: Answerable<A>, expectation: Expectation<any, A>) {...}.
    I tried changing it using this new Ensure thing but it did not work. Do you have an example for it? (I am probably just stupid atm)

@jan-molak
Copy link
Member

Hi @Ijee!

I can not find the Is class - do I have to implement that myself using protractor or is it somewhere else?

The Is class from 1.x has now been replaced with expectations that can be used with both Wait and Ensure. For example:

import { isClickable, Wait } from '@serenity-js/protractor';
import { Ensure } from '@serenity-js/core';

actor.attemptsTo(
  Wait.until(Form.Submit_Button, isClickable()),
  // but also:
  Ensure.that(Form.Submit_Button, isClickable()),
);

I can not find the TakeNotes ability. Do you plan on adding it back?

Yes, it will be added back in some form. If you need it right now you could copy the one from 1.x (source)

@step('') for performAs for my custom tasks is not available anymore? It doesn't say anything about removing it in the changelog.

In 1.x the @step annotation would emit events when the activity was started/finished. In 2.x this responsibility is now with the Actor who uses the description of an activity provided by its toString() method. This means that the only thing that the @step would do in 2.x would be to generate a toString()... which doesn't seem that useful.

In other words, instead of:

export class DoSomethingCool extends Interaction {

  @step('#actor does something cool')
  performAs(actor: UsesAbilities & AnswersQuestions): PromiseLike<void> {
       return SomeAbility.of(actor).doStuff();
  }
}

you can simply:

export class DoSomethingCool extends Interaction {

  performAs(actor: UsesAbilities & AnswersQuestions): PromiseLike<void> {
       return SomeAbility.of(actor).doStuff();
  }

  toString() {
      return '#actor does something cool';
  }
}

or even shorter:

import { Interaction } from '@serenity-js/core';

export DoSomethingCool = () =>
    Interaction.where(`#actor does something cool`, actor =>
        SomeAbility.of(actor).doStuff());

I also found that Check.whether(condition: boolean | Question | Question<PromiseLike>) {...} got changed to
Check.whether(actual: Answerable, expectation: Expectation<any, A>) {...}.
I tried changing it using this new Ensure thing but it did not work. Do you have an example for it?

You're correct. An Answerable is either a Question<Promise<value>>, a Question<value>, a Promise<value> or just a value.

This means that you could do things like:

Check.whether(process.env.BASE_URL, includes('dev'))
    .andIfSo(
        DoOneThing(),
    )
    .otherwise(
        DoSomeOtherThing(),
    )

But also:

Check.whether(Cookies.Consent_Form, isVisible())
    .andIfSo(
        Click.on(Cookies.Accept)
    )

You can find some examples in the specs

(I am probably just stupid atm)

I'm sure that's not the case :-)

Thanks for taking the time to try 2.x and report the issues! If you come across anything else, please let me know!

jan-molak added a commit that referenced this issue Aug 5, 2019
…uestion), which makes the Actor remember the answer to a question and Note.of(question), which makes the Actor retrieve the remembered value.

#318
@jan-molak
Copy link
Member

jan-molak commented Aug 5, 2019

@Ijee I've just added TakeNotes back in, here's an example of how you'd use it:

import { Note, TakeNote, TakeNotes } from '@serenity-js/core'
import { BrowseTheWeb, Target, Text } from '@serenity-js/protractor'
import { by, protractor } from 'protractor';

const Checkout = {
    VoucherCode: () => Target.the('voucher code').located(by.id('voucher')),
    AppliedVoucherCode: () => Target.the('voucher code').located(by.id('applied-voucher')),
};

const actor = Actor.named('Noah').whoCan(
    TakeNotes.usingAnEmptyNotepad(),
    BrowseTheWeb.using(protractor.browser),
);

actor.attemptsTo(
    TakeNote.of(Text.of(Checkout.VoucherCode())),
    // ... add the product to a basket, go to checkout, etc.
    Ensure.that(Checkout.AppliedVoucherCode(), equals(Checkout.VoucherCode())),
);

The cool thing about Note.of is that you can use it with assertions:

Ensure.that(Note.of(Checkout.AppliedVoucherCode()), equals('SUMMERSALE'))

or interactions:

Enter.theValue(Note.of(Checkout.VoucherCode())).into(Checkout.VoucherCodeField());

Hope this helps!

@nbarrett
Copy link
Contributor

nbarrett commented Aug 5, 2019

Noted - cheers! 👍

@abhinaba-ghosh
Copy link

Hi @jan-molak : any update on release dates of serenity-ks 2.0 officially?

@jan-molak
Copy link
Member

@abhinaba1080 - I decided to fix some bugs in Serenity/JS CLI before the release, which ended up becoming a re-write of the CLI... I'm almost finished with that though, so the last bit is the tutorials and more documentation. Thanks for your patience!

@abhinaba-ghosh
Copy link

@asnov - Since Photographer is Protractor-specific, he decided to move to the @serenity-js/protractor module (specs available here).

import { Photographer, TakePhotosOfFailures } from '@serenity-js/protractor';

new Photographer(new TakePhotosOfFailures())

Which reminds me that I should:

  • add a factory method to make the instantiation simpler, maybe something like Photographer.who(TakesPhotosOfFailures) 🤔
  • document that the Photographer has moved elsewhere. Maybe a migration guide could be useful?

@asnov does the Photographer working for you? Its not for me eventually. Can you share your serenity version and piece of configuration?

@jan-molak : i am really stuck, kindly look into this: #335

@jan-molak
Copy link
Member

@abhinaba1080 - I've replied in #335, so let's move this conversation there, please.

@jan-molak
Copy link
Member

All, I've moved the SerenityBDDReporter class to a dedicated module @serenity-js/serenity-bdd responsible for integrating Serenity/JS with Serenity BDD reporting CLI.

Additionally, the @serenity-js/serenity-bdd module ships with a brand new CLI wrapper, which you can use to download the Serenity BDD jar:

serenity-bdd update

and generate the reports:

serenity-bdd run

This means that you no longer need to use the old serenity-cli module and can switch to the new one at your convenience.

A more in-depth description of the new module can be found in its readme.

The new implementation has an improved downloader, which can restart the download should it be interrupted, as well as a better Java detection mechanism, so you should no longer see warnings on Linux-based systems.

Fun fact: the new CLI wrapper is written in Serenity/JS Screenplay ;-)

@jan-molak
Copy link
Member

Hi all,

I've just put together a small template project demonstrating the setup required to run tests using Serenity/JS v2 (alpha), Cucumber v5 and Protractor - https://github.com/serenity-js/serenity-js-cucumber-protractor-template

Thoughts and feedback welcome.

@ctaepper
Copy link
Author

ctaepper commented Oct 22, 2019

@jan-molak would you shed some light on this topic in 2.0? When I run tests using browserstack and multicapabilities I do not see any tagging of browsernames in the tests. Is this feature still pending in 2.0?

edit: it seems to omit the results from mutliple browsers. If I run the tests on 2 devices, the report overview does double the count of scenarios tested, but in the scenario details, I can only see one result

@jan-molak
Copy link
Member

Hi all,

I've just published a new @serenity-js/console-reporter module that supersedes the experimental (and now deleted!) ConsoleReporter class that used to ship with @serenity-js/core.

Have a look at the module's readme for full installation instructions.

To upgrade from the experimental ConsoleReporter to the new version, please install the new module:

npm install --save @serenity-js/console-reporter

and update your Protractor config:

// protractor.conf.js

- const { ConsoleReporter } = require('@serenity-js/core');
+ const { ConsoleReporter } = require('@serenity-js/console-reporter');

exports.config = {
  framework:      'custom',
    frameworkPath: require.resolve('@serenity-js/protractor/adapter'),
    serenity: {
      crew: [
-       new ConsoleReporter(),
+       ConsoleReporter.withDefaultColourSupport(),
      ],
      // other Serenity/JS config
    },
    // other Protractor config
 };

Please note that the new ConsoleReporter supports several colour themes, which you can choose by calling either of the following factory methods:

ConsoleReporter.withDefaultColourSupport()
ConsoleReporter.forMonochromaticTerminals()
ConsoleReporter.forDarkTerminals()
ConsoleReporter.forLightTerminals()

All the existing implementation examples have also been updated to use the new ConsoleReporter.

And here are some screenshots:
image

image

Thoughts and feedback welcome!

@abhinaba-ghosh
Copy link

This feature is killing.. But still it is alpha 😝

Can't wait for the official release..

@jan-molak
Copy link
Member

Can't wait for the official release..

Working on it 👨‍💻

@KyleFairns
Copy link
Contributor

KyleFairns commented Nov 28, 2019

@jan-molak I feel like the indentation is different when working with cucumber (in alpha-89, at the least), but the existing extra feedback from execution is definitely helpful.

You have the step, a single indentation, and then the serenity steps in a list, not indenting further when a new interaction is introduced (which may be intended, because it reduces noise), but it may be nice to have an option to be able to include some more noise with the interaction descriptions so the intent is clearer in the output, or to remove the description of the interactions (like "Wendy attempts to log in (4s 808ms)" in the examples below) in order to avoid confusion.

Current (based on the Mac Terminal, another terminal called Hyper [powered by electron] and also the Jetbrain's Webstorm terminal):

Given Wendy is using us as her supplier
    ✓ Wendy enables synchronisation with Angular (0ms)
    ✓ Wendy navigates to '/login' (1s 944ms)
    ✓ Wendy visits the login page (1s 945ms)
    ✓ Wendy waits up to 5s until the email field does become visible (146ms)
    ✓ Wendy enters 'yeahthisemailisfake@wendysemailprovider.com' into the email field (112ms)
    ✓ Wendy enters 'password' into the password field (47ms)
    ✓ Wendy clicks on the login button (48ms)
    ✓ Wendy waits for 2s 500ms (2s 505ms)
    ✓ Wendy attempts to log in (4s 808ms)

Expected (following the same pattern as shown in your previous screenshots):

Given Wendy is using us as her supplier
    Wendy attempts to log in
        ✓ Wendy enables synchronisation with Angular (0ms)
        ✓ Wendy navigates to '/login' (1s 944ms)
        ✓ Wendy visits the login page (1s 945ms)
        ✓ Wendy waits up to 5s until the email field does become visible (146ms)
        ✓ Wendy enters 'yeahthisemailisfake@wendysemailprovider.com' into the email field (112ms)
        ✓ Wendy enters 'password' into the password field (47ms)
        ✓ Wendy clicks on the login button (48ms)
        ✓ Wendy waits for 2s 500ms (2s 505ms)

Are you already aware of this, or should I create a ticket?

I'm wrong, but learning

@jan-molak
Copy link
Member

Hey @KyleFairns and thanks for your feedback!

The formatting reflects the structure of the tasks your actor performs.

The output in your example would've been produced in a scenario similar to the one below:

actor.attemptsTo(
  UseAngular.enableSynchronisation(),
  Navigate.to('/login'),
  Wait.until(emailField, isVisible()),
  Enter.theValue('yeahthisemailisfake@wendysemailprovider.com').into(emailField),
  Enter.theValue('password').into(passwordField),
  Click.on(loginButton),
)

If you introduced domain-specific tasks, for example:

const LaunchTheApp = () => 
  Task.where(`#actor launches the app`, 
    UseAngular.enableSynchronisation(),
    Navigate.to('/login'),
  );

const Authenticate = {
  using: (email: string, password: string) => 
    Task.where(`#actor authenticates using '${ username }' and password '${ password }'`,
        Wait.until(emailField, isVisible()),
        Enter.theValue(username).into(emailField),
        Enter.theValue(password).into(passwordField),
        Click.on(loginButton),
    ),
}

And used the following flow instead:

actor.attemptsTo(
  LaunchTheApp(),
  Authenticate.using('yeahthisemailisfake@wendysemailprovider.com', 'password'),
)

You'd see that the level of indentation reflects how deeply the tasks are nested.

Given Wendy is using us as her supplier
  Wendy Launches the app
    ✓ Wendy enables synchronisation with Angular (0ms)
    ✓ Wendy navigates to '/login' (1s 944ms)
  Wendy authenticates using 'yeahthisemailisfake@wendysemailprovider.com' and password 'password'       
    ✓ Wendy waits up to 5s until the email field does become visible (146ms)
    ✓ Wendy enters 'yeahthisemailisfake@wendysemailprovider.com' into the email field (112ms)
    ✓ Wendy enters 'password' into the password field (47ms)
    ✓ Wendy clicks on the login button (48ms)
# etc.

Does this make sense?

@KyleFairns
Copy link
Contributor

KyleFairns commented Nov 28, 2019

Apparently I was stumbling on the issue due to defining them as interactions instead of tasks (i.e. an interaction made of interactions) - but hadn't been able to find the 2.0 syntax for tasks before now (and didn't think it would be that simple)

Thanks for the help @jan-molak, and keep up the smashing work!

@jan-molak
Copy link
Member

jan-molak commented Dec 8, 2019

Hey guys, just to let you know, since Serenity/JS is eating up all the free time I have, I'm looking for alternative ways to sponsor its development going forward to make it more sustainable.

I thought I'd experiment with a Github Sponsors profile as a way to do it, so if you or your company find Serenity/JS useful, please consider buying me a coffee every now and then ;-)


@EshChn - thanks for being the first Github sponsor of Serenity/JS! 🙏
@rick-liu-tw - thanks for sponsoring Serenity/JS 🙏
@daydreamman - thanks for sponsoring Serenity/JS 🙏

@jan-molak
Copy link
Member

@ctaepper, @asnov, @owlran , @Ijee, @nbarrett, @abhinaba1080, @KyleFairns - thanks a million for helping me iron out the issues with Serenity/JS v2 🙇

I'm happy to announce that the official release is now available on NPM and the new website at https://serenity-js.org.

Please give it a try and let me know your thoughts on Twitter and our new Gitter Chat!

@abhinaba-ghosh
Copy link

abhinaba-ghosh commented Feb 3, 2020 via email

@jan-molak jan-molak unpinned this issue Feb 8, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants