by

Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
  • Jun 05 20:37
    rodrigo-costa-sofist edited #590
  • Jun 05 20:30
    rodrigo-costa-sofist edited #590
  • Jun 05 20:30
    rodrigo-costa-sofist opened #590
  • Jun 05 10:25
    Travis serenity-js/serenity-js@70a392b (dependabot/npm_and_yarn/types/node-12.12.44) passed (1524)
  • Jun 05 10:15
    Travis serenity-js/serenity-js@0edb4dd (dependabot/npm_and_yarn/typescript-3.9.5) passed (1522)
  • Jun 05 10:06

    dependabot-preview[bot] on npm_and_yarn

    (compare)

  • Jun 05 10:06
    dependabot-preview[bot] closed #587
  • Jun 05 10:06
    dependabot-preview[bot] commented #587
  • Jun 05 10:06
    dependabot-preview[bot] labeled #589
  • Jun 05 10:06
    dependabot-preview[bot] opened #589
  • Jun 05 10:06

    dependabot-preview[bot] on npm_and_yarn

    chore(deps-dev): bump @types/no… (compare)

  • Jun 05 10:02
    dependabot-preview[bot] labeled #588
  • Jun 05 10:02

    dependabot-preview[bot] on npm_and_yarn

    chore(deps): bump typescript fr… (compare)

  • Jun 05 10:02
    dependabot-preview[bot] opened #588
  • Jun 05 00:37

    jan-molak on lerna-3.18.3

    (compare)

  • Jun 05 00:37

    jan-molak on lerna-3.18.2

    (compare)

  • Jun 05 00:37

    jan-molak on mocha-6.2.2

    (compare)

  • Jun 05 00:37

    jan-molak on lerna-3.18.1

    (compare)

  • Jun 05 00:37

    jan-molak on lerna-3.18.0

    (compare)

  • Jun 05 00:37

    jan-molak on coveralls-3.0.7

    (compare)

Jan Molak
@jan-molak
Shouldn't be a biggie
Abhinaba Ghosh
@abhinaba-ghosh
Thanks. big help!
philicia
@tirzahtoh_twitter
When I launch my browser at 'https://studio-staging.xxx.io/login' there is a notification popup and two buttons Block, Allow in chrome browser, I am using cucumber protractor with SerenityJS, how can I disable this popup so I can move on to perform my automation in the login page.
Abhinaba Ghosh
@abhinaba-ghosh

Hi, can we Take note of n value and store it to a key, something like:

 TakeNote.of('myResponse', LastResponse.body())

And use it somewhere like:

 Note.of('myResponse')
Is that even possible? any leads?
Jan Molak
@jan-molak
@abhinaba-ghosh It's actually even simpler than that, TakeNote stores the answer to a given question under a key named after whatever the question's toString method returns
So all you need to do is
actor.attemptsTo(
  TakeNote.of(LastResponse.body()),
  Log.the(Note.of(LastResponse.body()),
)
The only potential downside to that is that you can have only one note on a given "topic" at a time. So for example
actor.attemptsTo(
  Send.a(GetRequest.to('/api/first')),
  TakeNote.of(LastResponse.body()),
  Send.a(GetRequest.to('/api/second')),
  TakeNote.of(LastResponse.body()),
  Log.the(Note.of(LastResponse.body()),   // that's the second response now
)
Jan Molak
@jan-molak
a potential way around it would be to give developers a way to override the key via a construct along the lines of
TakeNote.of(LastResponse.body()).as('first response'),
but that then opens the doors for a class of errors related to typos and is not something a compiler could help you detect
Jan Molak
@jan-molak
Having said that, I'd be happy to add this functionality if people need it
(If you do please feel free to raise a ticket and we can discuss it there)
Jan Molak
@jan-molak

When I launch my browser at 'https://studio-staging.xxx.io/login' there is a notification popup and two buttons Block, Allow in chrome browser, I am using cucumber protractor with SerenityJS, how can I disable this popup so I can move on to perform my automation in the login page.

It looks like Chrome blocks the popup window your app tries to create. Add --disable-popup-blocking to chromeOptions > args in your protractor.conf.js

    capabilities: {
        browserName: 'chrome',

        chromeOptions: {
            args: [
                '--disable-popup-blocking',
                // other args
            ]
        }
    }
Abhinaba Ghosh
@abhinaba-ghosh

The only potential downside to that is that you can have only one note on a given "topic" at a time. So for example

actor.attemptsTo(
  Send.a(GetRequest.to('/api/first')),
  TakeNote.of(LastResponse.body()),
  Send.a(GetRequest.to('/api/second')),
  TakeNote.of(LastResponse.body()),
  Log.the(Note.of(LastResponse.body()),   // that's the second response now
)

Hi @jan-molak , facing the exact. It is a good idea to introduce a key and store the value, so that we can make use of that any given time.

Jan Molak
@jan-molak
Thinking about it, there's one more downside to storing the answer under a custom string - we'd be losing type safety since at the time of retrieval we don't know the type of the answer stored in the notepad
so people would need to either specify the type they're hoping to get back, or get an any
So something like this:
Log.the(Note.of<number>('first response status'))
rather than
Log.the(Note.of(LastResponse.status()))
hmm, maybe it's not such a big deal
especially if it's opt-in
(type safety fans, please feel free to shout at me if you disagree :-) )
Jan Molak
@jan-molak
@abhinaba-ghosh - would you mind raising a ticket about it so that we don't forget to implement it?
philicia
@tirzahtoh_twitter

I notice the input value send to the input textfield includes the double quotation "", how do I get omit the "", and how do I debug the serenityJS to see the value of username? here is my code snippet for the task
export const EnterCredentials = {

of: (username: string | number, password: string | number) =>
    Task.where(`#actor enters username ${ username } and password ${ password }`,
        Enter.theValue(username).into(LoginPage.usernameInput),
        Enter.theValue(password).into(LoginPage.passwordInput),
        Click.on(LoginPage.loginButton),
    ),

}; and here is the code in the step defn: When(/(.) login with username (.) and password (.*)/, (actorName: string, username: string, password: string) =>
actorInTheSpotlight().attemptsTo(
EnterCredentials.of(username, password),
));

philicia
@tirzahtoh_twitter
I saw in the step definition this Before(() => engage(new Actors())); which is create the Actors object? how about the teardown? do we need to delete the Actors at the end of the test scenarios?
Jan Molak
@jan-molak
Hey @tirzahtoh_twitter!
The quotation is probably because of the regex you're using to match the cucumber step

For example, if your cucumber scenario says:

Given I login as "Jan" using "password"

the step definition would need to account for the quotes:

Given(/I login as "(.*?)" using "(.*?)"/, (username: string, password: string) => ....)
Also, remember you can use Cucumber parameter types instead of regexes - https://cucumber.io/docs/cucumber/cucumber-expressions/#parameter-types
Jan Molak
@jan-molak
To answer your second question, the easiest way to log the parameters you're passing to Serenity/JS is by using an interaction to Log:
import { Log } from '@serenity-js/core';

actorCalled(..).attemptsTo(
    Log.the(/* any static value, question or promise */)
)

I saw in the step definition this Before(() => engage(new Actors())); which is create the Actors object? how about the teardown? do we need to delete the Actors at the end of the test scenarios?

Good question! You don't need a teardown, Serenity will automatically dismiss any actors you used in your scenario.

Marco Tahat
@mtahat

@jan-molak Good morning guys, I am trying to retrieve text from input field and convert it to a Number. Text.of returns empty string, but I was able to get it using Value.of(). but when I tried to convert it to a number using Number.toFloat I get error saying Object of type Value is not compatible with String. How do i get the answer form any Question as a String? I tried also TakeNote.of and it also returned an object.

When(/^user enters the payment amount$/, () => 
    actorInTheSpotlight().attemptsTo(
       SafeWait.isClickable(PaymentOptionsUI.PaymentAmount, Duration.ofSeconds(30)),
       //TakeNote.of(Value.of(PaymentOptionsUI.PaymentAmount)),
       Log.the(Value.of(PaymentOptionsUI.PaymentAmount)),
       Log.the(Number.parseFloat(Value.of(PaymentOptionsUI.PaymentAmount)),
));

Log.the(Value.of(PaymentOptionsUI.PamnetAmount)),

Retruns: logs: [object Object] (2ms)
[test:execute:wip]       [object Object]:
[test:execute:wip]       '286.30'

Log.the(Number.parseFloat(Value.of(PaymentOptionsUI.PaymentAmount)),

Compile Error: Argument of type 'Value' is not assignable to parameter of type 'string

Any Help will be appreciated.
Thanks

philicia
@tirzahtoh_twitter
can I use playwright with SerenityJS?
Jan Molak
@jan-molak

Hey @mtahat - Value.of is intended to be used to retrieve a value attribute of an <input />. Value.of(PaymentOptionsUI.PaymentAmount) instantiates a Question, which is not compatible with Number.parseFloat which requires you to give it a string. What you can do is create a simple mapper that turns the string into a number:

const NumberFrom = (answerable: Answerable<string>) => 
    Question.about(`number from ${ answerable }`, actor => actor.answer(answerable).then(answer => Number.parseFloat(answer));

then you can:

actorInTheSpotlight().attemptsTo(
    Log.the(NumberFrom(Value.of(PaymentOptionsUI.PaymentAmount))),
);
And even better, you could create a question called PaymentAmount that does the conversion under the hood

can I use playwright with SerenityJS?

Hey @tirzahtoh_twitter! It is possible to extend Serenity/JS to integrate with Playwright the same way it integrates with Protractor, but it's not supported out of the box yet.

Marco Tahat
@mtahat
@jan-molak Thank you for your suggestion. I ended up creating new question to handle the payment and it did work like a charm! Awesome framework, I am planning to integrate detox ( mobile testing framework for ios and android) with Serenity. not sure if that will work but I really liked the Serenity framework and want to use it also for mobile testing..
Jan Molak
@jan-molak
Awesome, happy to help @mtahat :-) And thanks for your kind words, I'm glad you like it!
Sure, integrating Serenity with Detox sounds like a great idea! The syntax looks relatively similar to Protractor, so you could probably implement similar if not the same patterns
Please keep me posted on your work!
philicia
@tirzahtoh_twitter
Hi, I like to set different baseUrl for different env in the protractor.conf.js (dev/qa/prod) how can I do that? and what is the parameter I need to specify in my package.json to run the test. reference: https://github.com/serenity-js/serenity-js-cucumber-protractor-template/blob/master/protractor.conf.js
10 replies
philicia
@tirzahtoh_twitter

Hi, I have this locator defined in this page object class: export class LoginPage {
static usernameInput = Target.the('username input').located(by.id('username'));
static passwordInput = Target.the('password input').located(by.id('password'));
static loginButton = Target.the('login button').located(by.id('login-btn'));
} however, I noticed it didn't perform the automation on the password field, my task class is: export const EnterCredentials = {

of: (username: string | number, password: string | number) =>
    Task.where(`#actor enters username ${ username } and password ${ password }`,
        Enter.theValue(username).into(LoginPage.usernameInput),
        Enter.theValue(password).into(LoginPage.passwordInput),
        Click.on(LoginPage.loginButton),
    ),

}; this is a angular web app. is it got to do with the DOM structure. I tried the same code on a non-angular app, I saw it can enter both username and password and click on the login button and go to the next page.

3 replies
Jan Molak
@jan-molak
Hey folks, I've just released @serenity-js/serenity-bdd 2.9.0 - https://github.com/serenity-js/serenity-js/blob/master/CHANGELOG.md#290-2020-06-05
philicia
@tirzahtoh_twitter
I have a error message alert with the text "Invalid credentials for user" and in the DOM, it's a span <span class="ant-alert-description ng-tns-c5-0 ng-star-inserted" style=""><!--bindings={ "ng-reflect-nz-string-template-outlet": "Invalid credentials for user" }--><!---->Invalid credentials for user</span>. what locator should I use in my page object. can I use static errorInvalidCredentials = Target.the('error message').located(by.css('ant-alert-description')); and in my step definitions. how do I use the assertion to check if I get this alert message? thanks
philicia
@tirzahtoh_twitter
I have a select option dropdown, how do I select a value using SerenityJS API? where the DOM look like this: <select name="role"> <option value="GA">Global Admin> <option value="OA">Org Admin><option value="User">User ....
philicia
@tirzahtoh_twitter
when I have successfully login, I want to ensure the page goes to the dashboard. for example my baseurl is https://philicia.com and my dashboard is https:://philicia.com/dashboard. how can I use the Ensure to check it navigate to the /dashboard? Ensure.that(Navigate.to('/dashboard)); does not seem to work
philicia
@tirzahtoh_twitter
I have a DOM structure like this <div class="warning"> <span>"This is a hello world message"Please go to this link <a href="https://helloworld.com">pages for more information</span>. in my pageObject class, I added this static warningMessage = Target.the('warning message').located(by.className('warning')); how do I use this locator to verify/assert the text in the span, can I also include the href link?
}
philicia
@tirzahtoh_twitter
I have a feature file that used datatable like this: Background:
Given James is at the portal page
And he login to the portal
|name|role|
|James|global admin| in my step defnitions: my implementation of the step: const input = table.hashes();
I got a compilation error: error TS2345: Argument of type 'RegExp' is not assignable to parameter of type 'Expectation<any, unknown>'.
[test:execute] Property 'answeredBy' is missing in type 'RegExp' but required in type 'Expectation<any, unknown>'.
philicia
@tirzahtoh_twitter
I am trying to look for a SerenityJS equivalent of this step definition to read from datatable: @Given("^(?:.*) login as global administrator to perform application management$")
public void jamesLoginAsGlobalAdministratorToPerformApplicationManagement(DataTable dataTable) {
List<List<String>> list = dataTable.asLists(String.class);
String username = list.get(1).get(0);
String password = list.get(1).get(1);
philicia
@tirzahtoh_twitter
And(/(?:he|she|they) login to the portal with \"(.)\", \"(.)\", \"(.)\" and \"(.)\"/, .... I got the compiler complain on the And error TS2552: Cannot find name 'And'. Did you mean 'and'? when I changed to small case and, it also complain Argument of type 'RegExp' is not assignable to parameter of type 'Expectation<any, unknown>'.
Property 'answeredBy' is missing in type 'RegExp' but required in type 'Expectation<any, unknown>'.ts(2345)
philicia
@tirzahtoh_twitter
can I use the Wait.until in the attemptTo like this: actorInTheSpotlight().attemptsTo(
Wait.until(DashboardPage.geNewLink, isVisible()),
SelectNew(),
Wait.until(SPage.getNewLink, isVisible()), SelectSNew(), ....