Giter Site home page Giter Site logo

wlsf82 / protractor-helper Goto Github PK

View Code? Open in Web Editor NEW
44.0 4.0 14.0 666 KB

Write robust and flakiness-free tests with Protractor.

Home Page: https://wlsf82.github.io/protractor-helper/

License: MIT License

JavaScript 89.68% HTML 4.16% CSS 6.16%
protractor-helper protractor testing automation e2e-testing

protractor-helper's Introduction

protractor-helper

npm version npm weekly downloads code style: prettier Build Status license BCH compliance Known Vulnerabilities

🌏 Portuguese


This library contains helper functions that can be used together with Protractor for creating robust end-to-end tests.

Many of the helper functions on this library uses protractor.ExpectedConditions to ensure that the elements we want to interact with are in the correct state before interacting with them or running expectations on them. This helps on avoiding trying to interact with elements when they are still not ready for it, which helps on avoiding test flakiness.

Summary

Basic example

Let's say you want to create a test for the sign in happy path of an example application.

Example without using the protractor-helper module

Without this library the test could be written as something like this:

const EC = protractor.ExpectedConditions;
const DEFAULT_TIMEOUT_IN_MS = 5000;

describe("Sign in page", () => {
  it("successful sign in", () => {
    browser.get("https://example.com/sign-in");

    const emailField = element(by.id("email"));
    const passwordField = element(by.id("password"));
    const signinButton = element(by.id("signin"));

    browser.wait(EC.visibilityOf(emailField), DEFAULT_TIMEOUT_IN_MS);
    browser.wait(EC.visibilityOf(passwordField), DEFAULT_TIMEOUT_IN_MS);
    browser.wait(EC.elementToBeClickable(signinButton), DEFAULT_TIMEOUT_IN_MS);
    emailField.sendKeys("[email protected]");
    passwordField.sendKeys("validpassword");
    signinButton.click();

    const avatar = element(by.id("avatar"));

    browser.wait(EC.visibilityOf(avatar), DEFAULT_TIMEOUT_IN_MS);

    expect(avatar.isDisplayed()).toBe(true);
  });
});

Example using the protractor-helper module

The same test could be written as below, using the protractor-helper library.

const protractorHelper = require("protractor-helper");

describe("Sign in page", () => {
  it("successful sign in", () => {
    browser.get("https://example.com/sign-in");

    const emailField = element(by.id("email"));
    const passwordField = element(by.id("password"));
    const signinButton = element(by.id("signin"));

    protractorHelper.fillFieldWithText(emailField, "[email protected]");
    protractorHelper.fillFieldWithText(passwordField, "validpassword");
    protractorHelper.click(signinButton);

    const avatar = element(by.id("avatar"));

    protractorHelper.waitForElementVisibility(avatar);
  });
});

As you can see, by using the protractor-helper library the code is easier to read. Also, there is no need of unnecessary complexity.

Installation

Below it is described the process of Installation of such module.

Run npm install protractor-helper --save-dev to install the library as a dev dependency of your project.

How to use and examples

After installing the library you will need to require it in your test file (see below).

// foobar.spec.js

const protractorHelper = require("protractor-helper");

As soon as you have the library required in your test file you can start using its helper methods.

Here you'll find examples of usage of each of the available helper methods. (Important: read the notes on the top)

Available helpers

Below is the list of all available helpers in this library with your respective example:

setTimeout

This method allows to change the timeout duration of all protractor-helper methods called below setTimeout.

The timeoutInMilliseconds default is 5000 milliseconds

If called without passing an argument the timeout will be set to the default one.

An example of using this method is the need to ensure the screen loads within up to XX seconds, due to the request of the product management. This commonly occurs in ecommerce systems on special dates, such as Black Friday.

Example

isCurrentUrlDifferentFromBaseUrl

This method returns a boolean depending if the current url is different from the base url. No argument needed. Example

waitForAlertToBePresent

This method waits for an alert to be present on the page. Example

waitForElementPresence

This method waits for an element to be present in the DOM.

Note: An element may be present but not displayed. If you want to wait for the element to be displayed use the method waitForElementVisibility.

Example

waitForElementNotToBePresent

This method is the opposite of the previous one, so, it waits for an element not to be present in the DOM. Example

waitForElementVisibility

This method waits for an element to be visible in the page. Being displayed means not only that the element is present in the DOM, but also that is has a height and width that is greater than 0. Example

waitForElementNotToBeVisible

This method is the opposite of the previous one, so, it waits for an element not to be visible in the page. By saying not being displayed means that the element may be in the DOM, but not visible. Example

click

This method is used to click in an element as soon as it is in a clickable state. This means that the element is visible and enabled for clicking. Example

hoverAndClick

This method is used to hover over an element as soon as it is present in the DOM, and then click on it. Example

fillFieldWithText

This method fills an input field with a text as soon as such field is visible. Example

fillFieldWithTextAndPressEnter

This method fills an input field with a text as soon as such field is visible and then it simulates pressing the ENTER key from the keyboard. This method is useful in cases such as when doing a search and pressing the ENTER key, instead of having to fill the input field and clicking the search button, for example. Example

uploadFileIntoInputField

This method uploads a file in a file input field as soon as the file input field is present in the DOM. Example

clear

This method clears a text input field as soon as such field is visible. Example

clearFieldAndFillItWithText

This method clears a text input field as soon as such field is visible, and then it fills it with a text. Example

tap

This method performs a tap action on a clickable/tappable HTML element as soon as it is in a clickable/tappable state. This method is used when performing web mobile testing in mobile emulators, for example. Example

waitForTextToBePresentInElement

This method waits for a specific text to be present in a specific HTML element. Example

waitForTextNotToBePresentInElement

This method is the opposite of the previous one, so, it waits for a specific text not to be present in a specific HTML element. Example

waitForUrlToBeEqualToExpectedUrl

This method waits for the URL to be equal to an expected URL. Such method is useful when you want to continue performing actions on elements only when in the correct URL. Example

waitForUrlNotToBeEqualToExpectedUrl

This method waits for the URL not to be equal to an expected URL. Such method is useful when you want to continue performing actions on elements only when not in a specific URL. Example

waitForUrlToContainString

This method waits for the URL to contain an expected string. Such method is useful when you want to perform verifications based on the current URL. Example

waitForUrlNotToContainString

This method waits for the URL not to contain an expected string. Such method is useful when you want to perform verifications based on the current URL. Example

scrollToElement

This method is used to scroll up to an element on the page as soon as the element is visible in the DOM. Example

Using methods that start with 'wait' as test expectations (or test assertions)

Some of the available methods in this library can be used as test expectations, meaning that when using them you don't necessarily need to add an explicit expectation, such as something like this: expect(avatar.isDisplayed()).toBe(true);.

By using the protractor-helper library this could be implicit, like this: protractorHelper.waitForElementVisibility(avatar);. Here, implicit means that if the function waitForElementVisibility(avatar) has passed, it means that the element is visible, in other words, the element is displayed.

Below you can find the list of methods that can be used as expectations:

  • waitForElementPresence(element)
  • waitForElementNotToBePresent(element)
  • waitForElementVisibility(element)
  • waitForElementNotToBeVisible(element)
  • waitForTextToBePresentInElement(element, text)
  • waitForTextNotToBePresentInElement(element, text)
  • waitForUrlToBeEqualToExpectedUrl(expectedUrl)
  • waitForUrlNotToBeEqualToExpectedUrl(expectedUrl)
  • waitForUrlToContainString(string)
  • waitForUrlNotToContainString(string)

Note: if you use such methods as expectations they will not count as expectations, in a test report, for example, but if they fail a clear message will be shown to ease understanding why the test has failed. In the end, test reports are usually useful in cases where tests have failed and we need to understand why. If all tests are green there is nothing to worry about, at least not if they were well implemented.

Example of a test failure when using such methods as expectations

Let's look how a failure would looks like when using some of this methods as expectations.

  • Failure when using waitForElementPresence as expectation:
Failed: element with locator 'By(css selector, *[id="foo"])' is not present.
  • Failure when using waitForElementVisibility as expectation:
Failed: element with locator 'By(css selector, *[id="foo"])' is not visible.
  • Failure when using waitForTextToBePresentInElement as expectation:
Failed: text 'foo' not present on element with locator 'By(css selector, h1)'.

As you can see, the messages are clear and tell you exactly why the test has failed, such as in the previous example, where a specific text ('foo') is not present in a heading element (an element with css selector 'h1').

External resources

Here we list some external resources such as blog posts that mention (or use) the protractor-helper library.

Contributing

See contribution guidelines.

Code of conduct

Checkout the code of conduct.

Credits

The protractor-helper library was created by Walmyr Filho and is kept together with Paulo Gonçalves.

Follow them on Twitter (@walmyrlimaesilv and @paulorgoncalves.)

Thanks also to Lucas Amaral, Michiel Cuijpers, Ghazi Khan, Pedro Hyvo, Urvi Koladiya, and Zidrex Andag for contributing to the project.


MIT License

protractor-helper's People

Contributors

dependabot[bot] avatar doamaral avatar gkhan205 avatar jzandag avatar michielcuijpers avatar paulogoncalvesbh avatar pedrohyvo avatar urvi-k avatar wlsf82 avatar

Stargazers

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

Watchers

 avatar  avatar  avatar  avatar

protractor-helper's Issues

Remove 'errorMessage' argument

Description

To stop a bad practice that is occurring with the helper, we must remove the errorMessage argument from the methods.
The existing error message in the methods is already clear, pointing out the error line and suggesting what may have occurred. The user choosing which error message should appear is ultimately detrimental to it.

A deprecation warning must be implemented and we must have a transitional period.

Refactor 7 lines occurring 2 times in 2 files: inputFieldInteractions.js, misc.js

I've selected for refactoring 7 lines of code which are duplicated in 2 file(s) (1, 2). Addressing this will make our codebase more maintainable and improve Better Code Hub's Write Code Once guideline rating! πŸ‘

Here's the gist of this guideline:

  • Definition πŸ“–
    Do not copy code.
  • Why❓
    When code is copied, bugs need to be fixed in multiple places. This is both inefficient and a source of regression bugs.
  • How πŸ”§
    Avoid duplication by never copy/pasting blocks of code and reduce duplication by extracting shared code, either to a new unit or introduce a superclass if the language permits.

You can find more info about this guideline in Building Maintainable Software. πŸ“–


ℹ️ To know how many other refactoring candidates need addressing to get a guideline compliant, select some by clicking on the πŸ”² next to them. The risk profile below the candidates signals (βœ…) when it's enough! 🏁


Good luck and happy coding! :shipit: ✨ πŸ’―

Add MIT license badge

Is your feature request related to a problem? Please describe.
No.

Describe the solution you'd like
Just to add MIT license on the top of README.md
image

Describe alternatives you've considered
n/a

Additional context
n/a

Refactor 7 lines occurring 3 times in 2 files: inputFieldInteractions.js, misc.js

I've selected for refactoring 7 lines of code which are duplicated in 2 file(s) (1, 2, 3). Addressing this will make our codebase more maintainable and improve Better Code Hub's Write Code Once guideline rating! πŸ‘

Here's the gist of this guideline:

  • Definition πŸ“–
    Do not copy code.
  • Why❓
    When code is copied, bugs need to be fixed in multiple places. This is both inefficient and a source of regression bugs.
  • How πŸ”§
    Avoid duplication by never copy/pasting blocks of code and reduce duplication by extracting shared code, either to a new unit or introduce a superclass if the language permits.

You can find more info about this guideline in Building Maintainable Software. πŸ“–


ℹ️ To know how many other refactoring candidates need addressing to get a guideline compliant, select some by clicking on the πŸ”² next to them. The risk profile below the candidates signals (βœ…) when it's enough! 🏁


Good luck and happy coding! :shipit: ✨ πŸ’―

FYI, @PauloGoncalvesBH.

Document type's definitions

Now that we have an index.d.ts file, it would be nice to have some documentation around it so that users without a notion of types could benefit from it while reading the docs.

Refactor inputFieldInteractions.js:src/inputFieldInteractions.js

I've selected inputFieldInteractions.js:src/inputFieldInteractions.js for refactoring, which is a unit of 20 lines of code. Addressing this will make our codebase more maintainable and improve Better Code Hub's Write Short Units of Code guideline rating! πŸ‘

Here's the gist of this guideline:

  • Definition πŸ“–
    Limit the length of code units to 15 lines of code.
  • Why❓
    Small units are easier to analyse, test and reuse.
  • How πŸ”§
    When writing new units, don't let them grow above 15 lines of code. When a unit grows beyond this, split it in smaller units of no longer than 15 lines.

You can find more info about this guideline in Building Maintainable Software. πŸ“–


ℹ️ To know how many other refactoring candidates need addressing to get a guideline compliant, select some by clicking on the πŸ”² next to them. The risk profile below the candidates signals (βœ…) when it's enough! 🏁


Good luck and happy coding! :shipit: ✨ πŸ’―

setTimeout work only to some methods

Describe the bug
The setTimeout method work only to the following methods:

  • getBodyElementFromCurrentBrowserOrBrowserInstance
  • openNewBrowserInTheSamePage
  • isCurrentUrlDifferentFromBaseUrl
  • scrollToElementWhenVisible
  • scrollToElement

Expected behavior
Expected to work to any method.

Refactor 6 lines occurring 2 times in clickersAndTappers.js

I've selected for refactoring 6 lines of code which are duplicated in 1 file(s) (1, 2). Addressing this will make our codebase more maintainable and improve Better Code Hub's Write Code Once guideline rating! πŸ‘

Here's the gist of this guideline:

  • Definition πŸ“–
    Do not copy code.
  • Why❓
    When code is copied, bugs need to be fixed in multiple places. This is both inefficient and a source of regression bugs.
  • How πŸ”§
    Avoid duplication by never copy/pasting blocks of code and reduce duplication by extracting shared code, either to a new unit or introduce a superclass if the language permits.

You can find more info about this guideline in Building Maintainable Software. πŸ“–


ℹ️ To know how many other refactoring candidates need addressing to get a guideline compliant, select some by clicking on the πŸ”² next to them. The risk profile below the candidates signals (βœ…) when it's enough! 🏁


Good luck and happy coding! :shipit: ✨ πŸ’―

waitForElementVisibility not giving appropriate validation message

Describe the bug
I'm using protractorHelper for non angular website with cucumber js. I have set the value of waitForAngularEnabled to false, now I've observed that sometimes it gives error Error: function timed out, ensure the promise resolves within 5000 milliseconds for wait condition

Actual Error
Then I add new clinical item with name "test new clinical item" # src\clinical-items-builder\step-definitions\clinical-items-builder.steps.js:38
Error: function timed out, ensure the promise resolves within 5000 milliseconds

Wait condition
protractorHelper.waitForElementVisibility(element(by.css('.someclass');

Desktop (please complete the following information):

  • OS: Windows 10
  • Browser chrome
  • Version 86.0.4240.183

The automated release is failing 🚨

🚨 The automated release from the master branch failed. 🚨

I recommend you give this issue a high priority, so other packages depending on you could benefit from your bug fixes and new features.

You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. I’m sure you can resolve this πŸ’ͺ.

Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.

Once all the errors are resolved, semantic-release will release your package the next time you push a commit to the master branch. You can also manually restart the failed CI job that runs semantic-release.

If you are not sure how to resolve this, here is some links that can help you:

If those don’t help, or if this issue is reporting something you think isn’t right, you can always ask the humans behind semantic-release.


Invalid npm token.

The npm token configured in the NPM_TOKEN environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/.

If you are using Two-Factor Authentication, make configure the auth-only level is supported. semantic-release cannot publish with the default auth-and-writes level.

Please make sure to set the NPM_TOKEN environment variable in your CI with the exact value of the npm token.


Good luck with your project ✨

Your semantic-release bot πŸ“¦πŸš€

Fix outdated example

BDE5CC19-7592-4B94-A0F8-B86CD0937D15

This example is passing a deprecated last argument and it needs to be removed.

Note: find out if there are other cases like this and fix in the same PR.

Update CHANGELOG.md to make it more useful

Description

The CHANGELOG.md file needs to be updated with more useful information, and less useless info.

Other comments

Here are some ideas:

We could also update the README.md file with a link to the CHANGELOG.md file, and then have a call-to-action like: "Interested in the latest version of protractor-helper? Take a look at our changelog."

Implement Continuous Delivery

Implement Continuous Delivery

Objective:

  • Automate all repetitive task and use best practices from the open source community.
    • Generate tag, changelog, release, commit and publish after approving pull request.
  • Standardize commit message.

Steps:

Needed validation:

Validate locally if the commit message respect the conventional commit specification. Using git hooks commit-msg.

IGNORE - The automated release is failing 🚨

🚨 The automated release from the master branch failed. 🚨

I recommend you give this issue a high priority, so other packages depending on you could benefit from your bug fixes and new features.

You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. I’m sure you can resolve this πŸ’ͺ.

Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.

Once all the errors are resolved, semantic-release will release your package the next time you push a commit to the master branch. You can also manually restart the failed CI job that runs semantic-release.

If you are not sure how to resolve this, here is some links that can help you:

If those don’t help, or if this issue is reporting something you think isn’t right, you can always ask the humans behind semantic-release.


Invalid npm token.

The npm token configured in the NPM_TOKEN environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/.

If you are using Two-Factor Authentication, make configure the auth-only level is supported. semantic-release cannot publish with the default auth-and-writes level.

Please make sure to set the NPM_TOKEN environment variable in your CI with the exact value of the npm token.


Good luck with your project ✨

Your semantic-release bot πŸ“¦πŸš€

Create TypeScript definition file

Create an index.d.ts file so that users of the library can have IntelliSense functionality while writing their code.

Here's an example of the protractorHelper.setTimeout function signature.

Captura de Tela 2020-04-23 Γ s 01 09 15

Separate functions from `index.js` into smaller and less coupled modules

Description

This intends to address "writing shorter units of code" (code quality practice from BetterCodeHub).

Other comments

Regarding the separation of concerns, we could work with files for:

  • all functions related to waiting for elements' states;
  • all functions related to typing texts into fields, and clearing fields in forms;
  • functions related to clicking and tapping;
  • other functions (e.g, isCurrentUrlDifferentFromBaseUrl, setTimeout).

How to list in the summary the new methods?

How we can list all new methods on the summary in README.md?

Comments:

  • That new methods are only the old without the errorMessage parameter and with a more clear name.
  • On the methods that will be deprecated have a warning advising to use the new method.

Example:
click is a new method of clickWhenClickable without errorMessage parameter.
The clickWhenClickable will be deprecated on a future version.

  1. We list all methods? Old and new?
  2. We list only the new?
  3. We list only the old?
  4. We list the new with the old on a subtopic?

It's important to be clear to the user.

I think that the better option is the 1.

Move functions responsible for creating default messages to its own file

Description

To better organize code responsibilities, we could have a file called messageBuilder.js, for instance, which could live together with utils.js (I mean, in the same directory of it). Actually, we would migrate some of the functions from util.js to this new file, and leave there other utility functionalities, such as requiredParam and waitForElementToBeClickable.

Peer Dependency

Hi!

I have the problem, that I use protractor AND protractor-helper as dependencies. npm 3+ is not installing protractor, because it's peer dependency from protractor-helper.

Only working solutions:

  • installing protractor globally or particular (no way for me)
  • copy your index file after each module update and paste it to my own module (works but it's just a 'hack')

Can it be removed as peer dependency? Everbody knows that it's needed.

Preparation for async/await due to Control flow being removed from Selenium Webdriver

Description

Due to the Control Flow being removed from the newer version of the Selenium Webdriver (v.4), and the new beta version of Protractor (v.6.0.0-beta) being in accordance with such a change, protractor-helper needs to be adapted to work this way as well. Without it, at some point, it will break.

Other comments

I have already started working on this (https://github.com/wlsf82/protractor-helper/tree/prepare-protractor-helper-to-work-with-async-await).
For reference read the following: https://github.com/angular/protractor/blob/selenium4/CHANGELOG.md
We will need to update the documentation (notification of deprecations, instructions regarding migration to async/await, retro-compatibility), implement deprecation warnings, and test retro-compatibility with other projects using the lib (we could use some of our own projects for this).

Create tests for failure messages

Description

The idea is to increase the code coverage to ease the maintainers' job. The point is that when changing existing functionalities, to check that failures still work as expected, the existing "happy path" tests need to be manually updated and tested, to confirm that failures still work as expected. This is a waste of time when we know that such a process can be automated.

Other comments

We need to investigate how to test it. Maybe we should have unit tests for it.

Add method waitForAlertToBePresent

It'd be nice if protractor-helper had a method to wait for an alert to be present, so that I wouldn't need to write something like:

browser.wait(protractor.ExpectedConditions.alertIsPresent(), 5000);

Instead, I'd write something like:

protractorHelper.waitForAlertPresence() or protractorHelper.waitForAlertToBePresent().

Refactor 6 lines occurring 2 times in clickersAndTappers.js

I've selected for refactoring 6 lines of code which are duplicated in 1 file(s) (1, 2). Addressing this will make our codebase more maintainable and improve Better Code Hub's Write Code Once guideline rating! πŸ‘

Here's the gist of this guideline:

  • Definition πŸ“–
    Do not copy code.
  • Why❓
    When code is copied, bugs need to be fixed in multiple places. This is both inefficient and a source of regression bugs.
  • How πŸ”§
    Avoid duplication by never copy/pasting blocks of code and reduce duplication by extracting shared code, either to a new unit or introduce a superclass if the language permits.

You can find more info about this guideline in Building Maintainable Software. πŸ“–


ℹ️ To know how many other refactoring candidates need addressing to get a guideline compliant, select some by clicking on the πŸ”² next to them. The risk profile below the candidates signals (βœ…) when it's enough! 🏁


Good luck and happy coding! :shipit: ✨ πŸ’―

FYI, @PauloGoncalvesBH.

Element has class

Is your feature request related to a problem? Please describe.
I couldn't find in existing functions like to check if the element has class

Describe the solution you'd like
It would be good if something to check for the class present in an element like waitForClassToBePresentInElement

Implement deprecation warnings

Description

The functions getBodyElementFromCurrentBrowserOrBrowserInstance and openNewBrowserInTheSamePage will soon be deprecated, so we need to implement a mechanism to warn users about it.

Other comments

This will require research on how to do it.
Such an implementation can be useful for future changes as well.

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.