Skip to content

BonnierNews/zombieland

 
 

Repository files navigation

Zombieland

Tallahassee is great! It's powerful enough to test your applications entire client side. It's "hackable" enough to emulate most scenarios / quirks occurring in an actual browser, making it suitable for both feature and unit style testing. It's lightweight enough to not be an excuse for skimping on testing.

However it isn't perfect...

Proposed solution is to delegete all the DOM stuff to jsdom. Other key features are built as a toolkit of independent single purpose extensions.

Tallahassee

A browser module for loading pages, containing subsequent requests, persisting cookies etc.

More or less a convenient wrapper around *SuperTest, Tough Cookie and jsdom. The browser scope will also make it easy to test a session, or multiple parallell sessions, as opposed to a single page load.

SuperTest also enables passing along HTTP headers with a request which doesn't seem to be supported by the jsdom fromURL.

*See TODO for notes on the use of SuperTest

I really want the name Tallahassee to remain, although Columbus sounds more browsery.

Little Rock

A layout module implementing everything visual.

JSDOM does not provide a way to emulate layout out of the box. When major part of an application's client side JS consists of lazy loading / sticky behaviour etc. this is required.

Wichita

A resource module for running client side JS and resolving assets.

JSDOM does run scripts quite well. It does however not provide a controlled way to execute scripts at a convenient time. A pattern when testing something is asserting an element original state, running the scripts then asserting the element's new state. JSDOM will, like a browser, run any client script as soon as it has loaded making it tricky to run assertions prior to script execution.

Custom script executor enables running code at any given time. Also it enables running source code over a built resource which is good for rapid retesting.

Resolver enables "binding" script tags to files making the test suite less verbose and less prone to mistakes.

This could be achieved by extending the jsdom.ResourceLoader interface with some execution code - a sort of rewrite of existing package Wichita.

?

Any other key features?

Would be nice with at least 4 core modules so that all main characters are represented ;D

Drawbacks

JSDOM

JSDOM is kind of a black box compared to current Tallahassee browser environment. Read only properties are read only. Don't know if this is a big problem.

It is not as fully featured as it appears. Polyfills are required for some basic functions, such as fetch.

"Independent single purpose extensions"

The intention of making each tool independent sounds like a good idea but is it? Could make the API's overly complex! Does anyone want / need a setup like JSDOM, Tallahasse and Little Rock but not Whichita?

Custom script executor

Useful but feels wrong. The VM source text module is experimental.

TODO

  • Sleek, consistent APIs for all modules
  • Separate submodules to separate packages
  • Verified and tested CJS support
  • Forward JSDOM exports

Tallahassee

  • In-page navigation (clicking links etc.)
  • Reloading page
  • Unload browser and all its active jsdom instances
  • Expose network requests
  • Use node fetch / Response
    • Stable version of Nock
  • Containing requests to the app is currently done by setting up a nock scope around app origin which intercepts all reqs and proxies them through supertest. Not ideal for a bunch of reasons:
  • Scrap use of SuperTest. It's incorrectly used as an HTTP lib because of its ability to make requests to a server. Not having a listening server makes handling of client side requests messy. Calls to XMLHttpRequest needs to be intercepted and cookies will need to be handled manually. Also having the consumer starting / stopping their server once per test process would be more performant than doing it adhoc for each request.

Little Rock

  • Means to emulate fixed / sticky / hidden layout.
  • Further implement web APIs such as setters for Element.scrollLeft / .scrollTop
  • Cache for layout calculation. Clear on paints and DOM updates. Mutation observer would work it it were synchronous.
  • Paint method behaves different when used on an element and a selector. Maybe it should. Styles applied to element will overwrite previous styles. Styles applied to selector will be appended to stylesheet.
  • Scrolling behavior is very bare bones.
  • Painting with both "stylesheets" and "elements" might not cause expected behavior. When scrolling an initial paint will read from all style sources: first stylesheet then element. Then compiled diff will be applied to element giving it the "importance" of inline styles.
  • Convert to classes like JSDOM and the rest of the modules.
  • Further implement web APIs such as Element.scrollWidth / .scrollHeight
  • Limitations on scroll coordinates.
  • Automatic dimensions / coordinates. Maybe just paint method could take a list of elements with like { y: 'auto' } and it could stack them along the supplied axis, optionally updating supplied parent. Would be nice if it could work with dynamically injected elements / stylesheets as well.
  • Cleanup parent / child management - implicit relations to Window etc.

Whichita

  • Not using the ES module feature mustn't require the --experimental-vm-modules flag.
  • VM evaluation based on script type attribute.
  •  Respecting nomodule like modern / legacy browser.
  • Support for importing CJS modules in Script
  • Expose Script exports
  •  Cache for FS operations.
  • Have not been able to make a working example using fetch along with the community recommended polyfill. Did make it with another polyfill though :fingers_crossed:

Packages

No packages published

Languages

  • JavaScript 100.0%