GithubHelp home page GithubHelp logo

wixplosives / test-drive Goto Github PK

View Code? Open in Web Editor NEW
9.0 225.0 3.0 2.76 MB

Opinionated library for writing web component tests

License: MIT License

JavaScript 0.84% TypeScript 99.16%
testing web components dom layout chai matchers tdd async

test-drive's Introduction

Test Drive

npm version Build Status

Test Drive is an opinionated, yet framework-agnostic collection of tools, matchers and helpers for efficient Test Driven Development of web applications, GUIs and client-side components. Based on existing Open Source projects, as well as original contributions and ideas, it provides not only practical and efficient solutions for writing reliable tests, but also methodological guidelines based on long-term experimentation and hard-won lessons.

Installation

test-drive can be installed via the npm registry:

npm i test-drive --save-dev

If using TypeScript, several @types packages are required as well:

npm i @types/chai @types/sinon @types/sinon-chai @types/chai-dom @types/chai-as-promised --save-dev

test-drive exports sinon and chai via its main entry point. chai's expect is also directly exported, and is pre-loaded with chai-as-promised, chai-dom, sinon-chai, and chai-style assertions.

How to write tests

Locating your DOM parts: selectDOM()

selectDom(container: Element, attrName: string = 'data-automation-id')

Returns DOM selector function for the container, using attribute attrName. DOM selector is a function accepting one or more string identifiers.

Example:

const select = selectDOM(document.body, 'my-id');
const element = select('panel1', 'button-ok');

This code will find, inside the document body, element with attribute "myId" containing word "panel1" and inside it element with the same attribute containing word "button-ok".

element will be null, if such path cannot be resolved ("button-ok" or even "panel1" cannot be found).

The function select will throw an exception, if the path is ambiguous (e.g., "panel1" contains more than one "button-ok").

The .present() and .absent() matchers

Often, components have parts which are sometimes present, sometimes absent, depending on their configuration or state. As there are many possibilities how such "re-appearance" can be implemented, this kit provides a matcher that abstracts such internal implementation away.

Example:

expect(element).to.be.present();
expect(element).to.be.absent();

expect(element).not.to.be.present();
expect(element).not.to.be.absent();

"Presence" is defined as follows:

  • "element" is not null
  • "element" is an instance of Element
  • some part of "element" has real size (defined as ClientRect whose both width and height are greater than zero)

(This definition is inspired by jQuery's :visible selector, but not necessarily compliant with it.)

Layout Matchers

Using layout matchers, component developers can implement tests which assert relations between various parts of the component in terms of position in the document. Layout matchers abstract away the actual DOM structure and CSS rules, as they are based solely on absolute location of bounding rectangles. With the right combination of layout matchers, one should be able describe most of spatial relationships within components.

The parts are passed as references to HTMLElement.

Tests of layout matchers should provide exhaustive examples on how to use the matchers.

Placement

.insideOf(x) asserts that the subject is completely within the boundaries of element x.

.outsideOf(x) asserts the the subject is completely outside the boundaries of element x.

If the subject is partly inside and partly outside, none of the matchers passes.

Example:

expect(button).to.be.insideOf(panel);

Box Properties

Box properties of an element (width, height, left, top, right, bottom) can be measured and asserted with numeric matchers, such as:

expect(button1).to.have.width.equal(10);

Elements can also be compared with greaterThan(), above(), lessThan(), below(), at.least() and at.most():

expect(button1).to.have.height.greaterThan(button2);

At the same time, numeric comparisons will still work:

expect(button1).to.have.height.greaterThan(10);

Note that top and bottom will be compared as numbers. So bottom = 50 will still be "below" bottom = 100, even though visually it will, of course, appear "above".

Alignment

.horizontallyAligned("left" | "center" | "right, tolerance = 0.0)

.verticallyAligned("top" | "center" | "bottom", tolerance = 0.0)

The alignment matchers assert that all elements within a list are properly aligned with each other, with optional tolerance range.

Example:

expect([button1, button2, button3]).to.be.verticallyAligned('top', 1.5);

Sequence

.inHorizontalSequence({ distance = 0.0, tolerance = 1.0 })

.inVerticalSequence({ distance = 0.0, tolerance = 1.0 })

Asserts that all elements within a list form uninterrupted sequence, one adjacent to the other, without gaps.

Example:

expect([button1, button2, button3]).to.be.inHorizontalSequence({ distance: 10.0 });

Style

via chai-style

.style(styleName, styleValue)

Asserts that element has style attribute with matching value, regardless of browser-specific value.

Example:

expect(button).to.have.style('background-color', 'green');

License

MIT

test-drive's People

Contributors

alexshemeshwix avatar avivahl avatar cijoe1 avatar deduckproject avatar dependabot-preview[bot] avatar dependabot[bot] avatar electricmonk avatar tobich avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Forkers

azu zoosky

test-drive's Issues

package does not re-export typings for chai-as-promised

Consider code:

import { expect } from 'test-drive';

describe('chai-as-promised typings', () => {
  it('should compile', () => {
    expect(iThrow).to.be.rejected;
  })
})

async function iThrow() {
  throw 'I really throw';
}

E.R. It compiles;
A.R. Property 'rejected' does not exist on type 'Assertion';

Add matcher for distances between elements in sequence

It would be useful to specify an exact distance between a sequence of elements, or a distance relaxed by some tolerance. The matcher should take an options object for specifying behavior.

i.e. expect(element).to.be.inHorizontalSequence({ expectedDistance: '10px', tolerance: '5px' })

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.