Giter Club home page Giter Club logo

shakespeare's Introduction

Shakespeare logo Shakespeare

Build Sonar Quality Gate Sonar Coverage Maven Central

A framework helping to write tests like screenplays. It is based on the ideas from Page Objects Refactored by Antony Marcano, Andy Palmer & John Ferguson Smart, with Jan Molak.

Please refer to the Manual for further information on how to use or extend Shakespeare.

If you'd like to contribute to the project, please read the contributing guide and out code of conduct.

shakespeare's People

Contributors

dependabot-preview[bot] avatar dependabot[bot] avatar marlis-l avatar mkutz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

shakespeare's Issues

Document timeout and interval for Retryables

Currently there's no explicit documentation for setting the timeout and interval on Retryables in the manual, but only in the JavaDoc.

The most common use cases and default setting should be documented in the manual.

Reporting

Increase visibility what happens, especially when things go wrong, e.g. via logging/text, but also via images/videos/files when Selenium is involved.

Slf4jReporter prints sub-reports in wrong order

It seems sub reports are printed in random order, but should be chronologically.

Example:

09:18:21.444 [Test worker] INFO  Romeo - Romeo does Register[emailAddress=EmailAddress[[email protected]]] ✓ 16s
├── Romeo does EnterAddress[address=Address[firstName=Romeo, lastName=Montague, company=Montague Ltd., addressLine1=515 W Verona Ave, addressLine2=, city=Verona, state=Wisconsin, zipCode=53593, homePhone=(202) 762-1401, mobilePhone=, addressAlias=Home]] ✓ 1s69ms
├── Romeo does EnterPersonalInformation[personalInformation=PersonalInformation[title=MR, firstName=Romeo, lastName=Montague, password=jul13t, dateOfBirth=1999-02-14]] ✓ 2s973ms
├── Romeo does StartRegistration[emailAddress=EmailAddress[[email protected]]] ✓ 309ms
├── Romeo does NavigateToSignInPage[] ✓ 2s263ms
└── Romeo does SubmitRegisterForm[] ✓ 2s282ms

should actually be (according to execution order):

09:18:21.444 [Test worker] INFO  Romeo - Romeo does Register[emailAddress=EmailAddress[[email protected]]] ✓ 16s
├── Romeo does NavigateToSignInPage[] ✓ 2s263ms
├── Romeo does StartRegistration[emailAddress=EmailAddress[[email protected]]] ✓ 309ms
├── Romeo does EnterPersonalInformation[personalInformation=PersonalInformation[title=MR, firstName=Romeo, lastName=Montague, password=jul13t, dateOfBirth=1999-02-14]] ✓ 2s973ms
├── Romeo does EnterAddress[address=Address[firstName=Romeo, lastName=Montague, company=Montague Ltd., addressLine1=515 W Verona Ave, addressLine2=, city=Verona, state=Wisconsin, zipCode=53593, homePhone=(202) 762-1401, mobilePhone=, addressAlias=Home]] ✓ 1s69ms
└── Romeo does SubmitRegisterForm[] ✓ 2s282ms

Simplified the current order is:

root
├ D
├ C
├ B
├ A
└ E

Interestingly this order seems to be consistent: when the test is re-run it does not change.

Shorten filenames in FileReporter

Filenames can currently be indefinitely long (due to activity toString and actor names). This should be reduced to not exceed 255 charters in total.

Default Abilities and Facts

Setting up an Actor for a number of complex test cases can lead to a lot of duplicate code.

In order to reduce this, any Actor could have a set of default Abilities and/or Facts that are available or created on demand.

Add documentation

  • Getting started
  • Actors
  • Abilities
  • Tasks
  • Questions
  • Retryables
  • Facts
  • Module Selenium
  • Module Retrofit

Base URL is opened whenever getWebDriver is called

Since v0.5 the base URL is opened every time getWebDriver is called. Effectively resetting any previous navigation.

As getWebDriver is usually called at the beginning of any web-based Task or Question, this is a critical bug.

The base URL should only be navigated to, if no other navigation already happened. This is usually the case when the current URL is not equal to about:blank.

Allow to set scope in Oauth2Api

Affected: retrofit

Describe the bug
Currently the Oauth2Api does not allow to set a scope (e.g. openid).

We need a way to define a scope.

Add retry limit

In our team it would be preferred to limit the retries to a certain number.

Describe the solution you'd like

We would need two new variables in the Actor class. The variable maxRetries should be overridable.
Integer retryNumber = 0
Integer maxRetries = 0

Currently in the Actor.class the check looks like this:
if (question.acceptable(lastAnswer)) { reporters.forEach(reporter -> reporter.success(this, question, answer)); return answer; }
It would need to be replaced by a wrapper function:



if (question.acceptableWrapper(lastAnswer)) { reporters.forEach(reporter -> reporter.success(this, question, answer)); return answer; }

default boolean acceptableWrapper(A answer){ if(maxTries!=0 && retryNumber>maxRetries) return answer tryNumber++ acceptable(answer) }

We currently use our own code to do the same. This would be a cleaner approach and it adds a valuable feature to the framework.

Support multi-lined reports

Currently a LogReport for a Task or Question will always write exactly one line.

Readability would be improved if there was a line wrap, e.g. for long answers.

Another application for this would be custom supplements. For example, FileReporters could add their written file paths to the current LogReport.

Add JSON reporter

Is your feature request related to a problem? Please describe.
We need a structured report format for a service that will trigger Shakespeare-based automation scripts and return a report via an HTTP interface.

Describe the solution you'd like
We suggest to use JSON as base structure. The concrete format is an implementation detail, but should be stable.

Describe alternatives you've considered
XML or similar formats would also work, but is unnecessarily complicated to create.

Slf4jReporter does not clear its root report causing duplicate reports

The Slf4jReporter does not seem to clear its currentRootReport when it was logged. Due to that reports are being re-logged in later reports.

Example:

09:18:21.444 [Test worker] INFO  Romeo - Romeo does Register[emailAddress=EmailAddress[[email protected]]] ✓ 16s
├── Romeo does EnterAddress[address=Address[firstName=Romeo, lastName=Montague, company=Montague Ltd., addressLine1=515 W Verona Ave, addressLine2=, city=Verona, state=Wisconsin, zipCode=53593, homePhone=(202) 762-1401, mobilePhone=, addressAlias=Home]] ✓ 1s69ms
├── Romeo does EnterPersonalInformation[personalInformation=PersonalInformation[title=MR, firstName=Romeo, lastName=Montague, password=jul13t, dateOfBirth=1999-02-14]] ✓ 2s973ms
├── Romeo does StartRegistration[emailAddress=EmailAddress[[email protected]]] ✓ 309ms
├── Romeo does NavigateToSignInPage[] ✓ 2s263ms
└── Romeo does SubmitRegisterForm[] ✓ 2s282ms
09:18:21.507 [Test worker] INFO  Romeo - Romeo does Register[emailAddress=EmailAddress[[email protected]]] ✓ 16s → true
├── Romeo does SubmitRegisterForm[] ✓ 2s282ms
├── Romeo does EnterAddress[address=Address[firstName=Romeo, lastName=Montague, company=Montague Ltd., addressLine1=515 W Verona Ave, addressLine2=, city=Verona, state=Wisconsin, zipCode=53593, homePhone=(202) 762-1401, mobilePhone=, addressAlias=Home]] ✓ 1s69ms
├── Romeo does EnterPersonalInformation[personalInformation=PersonalInformation[title=MR, firstName=Romeo, lastName=Montague, password=jul13t, dateOfBirth=1999-02-14]] ✓ 2s973ms
├── Romeo does StartRegistration[emailAddress=EmailAddress[[email protected]]] ✓ 309ms
├── Romeo does NavigateToSignInPage[] ✓ 2s263ms
└── Romeo checks LoginStatus[] ✓ 56ms → true

should actually be

09:18:21.444 [Test worker] INFO  Romeo - Romeo does Register[emailAddress=EmailAddress[[email protected]]] ✓ 16s
├── Romeo does EnterAddress[address=Address[firstName=Romeo, lastName=Montague, company=Montague Ltd., addressLine1=515 W Verona Ave, addressLine2=, city=Verona, state=Wisconsin, zipCode=53593, homePhone=(202) 762-1401, mobilePhone=, addressAlias=Home]] ✓ 1s69ms
├── Romeo does EnterPersonalInformation[personalInformation=PersonalInformation[title=MR, firstName=Romeo, lastName=Montague, password=jul13t, dateOfBirth=1999-02-14]] ✓ 2s973ms
├── Romeo does StartRegistration[emailAddress=EmailAddress[[email protected]]] ✓ 309ms
├── Romeo does NavigateToSignInPage[] ✓ 2s263ms
└── Romeo does SubmitRegisterForm[] ✓ 2s282ms
09:18:21.507 [Test worker] INFO  Romeo - Romeo checks LoginStatus[] ✓ 56ms → true

Automatically open a base URL in BrowseTheWeb if provided

Most of the time there will be one base URL that should always be called at the beginning of a test. That URL should be added as a parameter to BrowseTheWeb and be automatically called, e.g. within getWebDriver, so all tests can rely on that setting.

Actions/Interactions

Hi again,

What is your view on actions/interactions?

Serenity/JS interactions are named using the vocabulary of the solution domain, so: "Click on a button", "Enter password into a form field" or "Send a request", and are focused on doing one thing and one thing only.

If you're considering implementing an interaction that performs more than one logical activity (i.e. checks if the button is visible and then clicks on it if is), consider implementing separate interactions for separate responsibilities and composing them together using a task.

I usually don't reference Serenity Java core as it's huge and way to complex for my liking.

The Serenity JS core is much more compact and closer to Shakesphere.

I would like to provide out of the box actions/interactions

Actor.named('Ernest').whoCan(Log.the("Current page", Website.title(), Website.url()));
Actor.named('Ernest').whoCan(WriteToStream.of(process.stdout));

I would like to be able to create a busines level task which is composed of multiple interactions.

// Task    
Actor.named('Ernest').whoCan(Create.Order(order));

// Actions
 actor.attemptsTo(
   Send.a(PostRequest.to('/orders/, order)),
   Ensure.that(LastResponse.status(), equals(200)),
   ...
 );

Would you consider adding this? Im pretty sure I will add it but wanted to first get your opinion.

Remeber Answers Automatically

When answering a Question, the Actor could remember the answer automatically.

To be considered:

Answers can be any type (incl. String, Integer etc.).
The current implementation of the Actor's memory allows only one instance of a type. Unintended overwrites of memories could happen easily.
Both would be mitigated if the Answer needs to be a Fact to be remembered.

The alternative would be changing the Actor's memory in which memories can be any type but need to be named (key/value store).

DockerWebDriverSupplier fails with SessionNotCreatedException

Affected

  • core
  • selenium
  • retrofit
  • testutils
  • manual
  • other/project

Describe the bug
When using DockerWebDriverSupplier, various exceptions are being thrown.

To reproduce
Run DockerWebDriverSupplierTest

DockerWebDriverSupplierTest > getTest1(BrowserType) > org.shakespeareframework.selenium.DockerWebDriverSupplierTest.getTest1(BrowserType)[3] FAILED
    io.github.bonigarcia.wdm.config.WebDriverManagerException at DockerWebDriverSupplierTest.java:22
        Caused by: io.github.bonigarcia.wdm.config.WebDriverManagerException at DockerWebDriverSupplierTest.java:22
            Caused by: org.openqa.selenium.SessionNotCreatedException at DockerWebDriverSupplierTest.java:22

Support

Hi,

I am currently working some Gauge modules (will make public in a few days) to make testing easier. I shamelessly use your code but I made some adjustments including:

  • adding Cast, Stage and Director
  • changing Fact to Memory and allowing to remember a question
  • Adding pronoun support to actor
  • basic assertion support but I will probably remove it.

I like the light approach and would like to support you. The serenity lib is way to big and confusing.

If you don't mind I would like to have a small chat (possibly video) and find out what your plans are and check if there is some way I can support you if the directions are aligned.

What do you think?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.