2.2.0 • Published 5 years ago

@dxworks/rite v2.2.0

Weekly downloads
-
License
MIT
Repository
github
Last release
5 years ago

Rite

npm i --save-dev @dxworks/rite

This lib provides:

  • Runner: run tests in both node and browser(puppeteer & puppeteer-firefox) environments.
  • Wrapper: around zora
  • Helper: describePage for setting up e2e test running in node using puppeteer or puppeteer-firefox

It's a fork of riteway using zora instead of tape.

Test assertions that always supply a good bug report when they fail.

  • Readable
  • Isolated/Integrated
  • Thorough
  • Explicit RITEway forces you to write Readable, Isolated, and Explicit tests, because that's the only way you can use the API. It also makes it easier to be thorough by making test assertions so simple that you'll want to write more of them. There are 5 questions every unit test must answer. RITEWay forces you to answer them.
  1. What is the unit under test (module, function, class, whatever)?
  2. What should it do? (Prose description)
  3. What was the actual output?
  4. What was the expected output?
  5. How do you reproduce the failure?

~Eric Elliott

Runner

Setup

{
  "scripts": {
    "test:node": "npx rite  test/node/**/*.test.js",
    "test:dom": "npx rite -p test/dom/**/*.test.js",
    "test:dom-firefox": "npx rite -p test/dom/**/*.test.js",
    "test:node-coverage": "c8 npm run test:node",
    "test:dom-coverage": "npx rite -p -cov test/dom/**/*.test.js",
  },
  "devDependencies": {
    "@dxworks/rite": "latest",
    "c8": "latest",
  }
}

Node

No flags required npx rite <glob pattern | file path>

Puppeteer

npx rite -p <glob pattern | file path>

Additional flags

FlagTypeAliasUsage
--puppetBoolean-prun test(s) in puppeteer
--coverageBoolean-cgenerate puppeteer coverage
--rootString-rpoint puppeteer server at a root directory for assets
--templateString-tpath to template function to be used by puppeteer runner. example
--firefoxBoolean-frun test in puppeteer-firefox requires npm i -D puppeteer-firefox
--browserBoolean-bdebug puppeteer tests running them in headless mode = false

Wrapper

Example: Basic

import { describe } from '@dxworks/rite';
const sum = (...args) => {
  if (args.some(v => Number.isNaN(v))) throw new TypeError('NaN');
  return args.reduce((acc, n) => acc + n, 0);
};

describe('sum()', assert => {
  const should = 'return the correct sum';
  assert({
    given: 'no arguments',
    should: 'return 0',
    actual: sum(),
    expected: 0,
  });

  assert({
    given: 'zero',
    should,
    actual: sum(2, 0),
    expected: 2,
  });

  assert({
    given: 'negative numbers',
    should,
    actual: sum(1, -4),
    expected: -3,
  });
});

Example: Try

import { describe, Try } from '@dxworks/rite';
const sum = (...args) => {
  if (args.some(v => Number.isNaN(v))) throw new TypeError('NaN');
  return args.reduce((acc, n) => acc + n, 0);
};

describe('sum()', assert => {
  assert({
    given: 'NaN',
    should: 'throw',
    actual: Try(sum, 1, NaN),
    expected: new TypeError('NaN'),
  });
});

Example: Async

import { describe } from '@dxworks/rite';
const resolveAfter = () =>  new Promise(resolve => {
  setTimeout(() => {
    resolve('resolved');
  }, 50);
});

describe('resolveAfter()', async assert => {
  const actual = await resolveAfter();
  assert({
    given: 'promise',
    should: 'resolve',
    actual,
    expected: 'resolved',
  });
});

Example: Skip

import { describe } from '@dxworks/rite';
describe.skip('skip()', assert => {
  assert({
    given: 'describe.skip',
    should: 'be equal to tape.skip',
    actual: 'skipped test',
    expected: 'test',
  });
});

Example: utilities for puppeteer tests

  • fixture: htmlElement wrapper
  • nextFrame: promise that lets you wait for next frame before evaluating dom change
import { describe, fixture, nextFrame } from '@dxworks/rite';
import { query } from '@dxworks/dom-utils';
import './delegated-components';

describe('delegatedListener(): shadow', async assert => {
  const { cleanup } = await fixture('<dl-shadow></dl-shadow>');
  const [el] = query('dl-shadow');
  assert({
    given: 'empty dl-shadow',
    should: 'have aria-hidden attribute',
    actual: el.hasAttribute('aria-hidden'),
    expected: true,
  });
  el.innerHTML = '<span></span>';
  await nextFrame();
  const newValue = el.getAttribute('aria-hidden');
  assert({
    given: 'not-empty dl-shadow',
    should: 'aria-hidden attribute to be ',
    actual: newValue,
    expected: 'false',
  });
  cleanup();
});

Helpers: describePage()

Example

import { html } from '@dxworks/utils';
import { describePage } from '@dxworks/rite/helpers';
import { servor } from '../src/servor';

export const testPage = () => html`
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>test servor</title>
</head>
  <test-fixture>
    <span>hello world</span>
  </test-fixture>
</html>`;

describePage('watch()', async (assert, page) => {
  const server = await servor({ browser: false, reload: false, page: testPage });
  await page.goto(server.info.uri);
  const fixture = await page.$eval('test-fixture', el => el.innerHTML);
  const title = await page.$eval('title', el => el.innerHTML);
  assert({
    given: 'server start',
    should: 'return a body content',
    actual: fixture,
    expected: html`<span>hello world</span>`,
  });
  assert({
    given: 'server start',
    should: 'have the following title',
    actual: title,
    expected: 'test servor',
  });
  server.stop();
});