Quixote
CSS unit and integration testing
Install / Use
/learn @jamesshore/QuixoteREADME
Quixote - CSS Unit and Integration Testing
Quixote is a library for testing CSS. It's fast—over 100 tests/second—and has a powerful API. You can use it for unit testing (test your CSS files directly) or integration testing (test against a real server). Either way, your tests check how HTML elements are actually rendered by the browser.
Quixote is unique for its ability to test how elements relate to each other. For example, you can test if one element is below another element, or how an element compares to the browser's viewport.
Example test:
// 'frame' is the Quixote test frame. See below for complete examples.
var header = frame.get("#header");
var navbar = frame.get(".navbar");
navbar.top.should.equal(header.bottom); // the navbar is immediately below the header
navbar.width.should.equal(frame.viewport().width); // the navbar is exactly as wide as the viewport
Example output:
top edge of '.navbar' should be 13px higher.
Expected: 50px (bottom edge of '#header')
But was: 63px
Quixote runs in the browser and works with any test framework. You can even test multiple browsers simultaneously by using a tool such as Karma or Test'em. It works in modern desktop browsers, mobile browsers, and IE 8+.
Resources
- API Documentation
- Complete Example
- Browsers Tested for This Release
- Change Log
- Roadmap
- Contributing
- License (MIT)
Installation
$ npm install quixote
Or download dist/quixote.js.
Quixote is a UMD module, which means it will work with CommonJS and AMD module loaders. If you just load the file using a <script> tag, Quixote will be available via the global variable quixote.
Usage
Quixote runs in the browser and works with any test framework. The following examples use Karma, Mocha, and Chai.
Quixote works by rendering elements in an iframe and allowing you to check how they were rendered. Under the covers, it uses the getComputedStyle() and getBoundingClientRect() DOM APIs.
To use Quixote, follow these steps:
- Choose your test style
- Install a test framework
- Serve your test files
- Set up your tests
- Test your code
See the example directory for a seed project containing a complete example.
Note: When testing Safari and Chrome on Mac OS X, make sure the browser windows are visible. When the windows aren't visible, Mac OS lowers their priority and the tests will run very slowly or time out.
1. Choose your test style
Quixote can be used in a unit-testing style or an integration-testing style (or both).
Unit Test Style
Use the unit test style when you want to test-drive individual CSS rules. In the unit test style, you'll use Quixote to:
- Load your CSS file
- Create elements that are styled by your CSS
- Confirm that the elements are displayed correctly.
A Quixote unit test might be used to test-drive a "button" class:
.button {
display: block;
width: 100%;
text-align: center;
text-transform: uppercase;
text-decoration: none;
}
The test code would look like this:
var assert = require("chai").assert;
var quixote = require("quixote");
describe("Button", function() {
var frame;
var container;
var button;
before(function(done) {
frame = quixote.createFrame({
stylesheet: "/base/src/client/screen.css"
}, done);
});
after(function() {
frame.remove();
});
beforeEach(function() {
frame.reset();
container = frame.add(
"<div>" +
" <a id='button' class='button' href='#anything'>foo</a>" +
"</div>"
);
button = frame.get("#button");
});
it("fills its container", function() {
button.width.should.equal(container.width);
});
it("has styled text", function() {
assert.equal(button.getRawStyle("text-align"), "center", "should be centered");
assert.equal(button.getRawStyle("text-decoration"), "none", "should not be underlined");
assert.equal(button.getRawStyle("text-transform"), "uppercase", "should be uppercase");
});
});
Integration Test Style
Use the integration test style when you want to test a complete web page. In the integration test style, you'll use Quixote to:
- Load your URL
- Get elements from the page
- Confirm that the elements are displayed correctly.
Imagine a site with a home page that contained a logo at the top and a nav bar below it. The logo is centered and the nav bar stretches the width of the window. The integration test for that page would look like this:
var assert = require("chai").assert;
var quixote = require("quixote");
describe("Home page", function() {
var BACKGROUND_BLUE = "rgb(65, 169, 204)";
var WHITE = "rgb(255, 255, 255)";
var MEDIUM_BLUE = "rgb(0, 121, 156)";
var frame;
var logo;
var navbar;
before(function(done) {
frame = quixote.createFrame({
src: "/", // the server under test must be proxied to localhost
width: 800
}, done);
});
after(function(done) {
frame.remove();
});
beforeEach(function(done) {
frame.reload(done);
});
beforeEach(function() {
logo = frame.get("#logo");
navbar = frame.get("#navbar");
});
it("has an overall layout", function() {
logo.top.should.equal(12, "logo should be at top of page");
logo.center.should.equal(frame.page().center, "logo should be centered");
assert.equal(logo.getRawStyle("text-align"), "center", "logo alt text should be centered");
navbar.top.should.equal(logo.bottom.plus(10), "navbar should be below logo");
navbar.left.should.equal(frame.page().left, "navbar should be flush to left of page");
navbar.width.should.equal(frame.page().width, "navbar should stretch the width of window");
});
it("has a color scheme", function() {
assert.equal(frame.body().getRawStyle("background-color"), BACKGROUND_BLUE, "page background");
assert.equal(logo.getRawStyle("color"), WHITE, "logo text");
assert.equal(navbar.getRawStyle("background-color"), MEDIUM_BLUE, "navbar background color");
assert.equal(navbar.getRawStyle("color"), WHITE, "navbar text");
});
it("has a typographic scheme", function() {
// etc
});
});
2. Install a test framework
To begin, you'll need a way of running tests in the browser. You can use any test framework you like.
If you don't already have a preferred test framework:
- Install Karma. Karma runs your test suite in multiple browsers simultaneously.
- Install Mocha. Mocha is a test framework. It organizes and runs your tests.
- Install Chai. Chai is an assertion library. It allows you to check results.
If you're using Karma, you may also want to use the karma-quixote plugin. This plugin will automatically load Quixote into the global quixote variable for you.
3. Serve your test files
Quixote gets your CSS and HTML files by loading URLs. You'll need to configure your test tool to make sure they're available. For integration tests, you'll need to proxy your server to localhost to avoid browser security errors.
Unit Test Style
In the unit test style, you load your CSS files directly. If you're using Karma, you can do it by modifying the files parameter in karma.conf.js. By default, they'll be available off of the /base/ directory.
files: [
// ...
{ pattern: 'src/client/screen.css', included: false }
// The 'included' parameter prevents Karma from automatically loading your CSS.
],
Integration Test Style
In the integration test style, you load an HTML page that's styled by your CSS. Because of browsers' security rules, the file must be served from the same server as your test, which means your test server will have to proxy the real server.
If you're using Karma, you can do it by setting the proxies parameter in karma.conf.js. In most cases, you'll want to proxy your server under test to the root directory, which means you'll also want to move the Karma runner from the root to a different directory. You can do that with the urlRoot parameter.
urlRoot: '/karma/'
proxies: {
'/': 'http://server_under_test/'
},
Normally, to capture a browser for Karma, you visit http://localhost:9876. With this configuration, you would visit http://localhost:9876/karma instead. Visiting http://localhost:9876 will show you the proxied server under test.
4. Set up your tests
Now you can write your tests. Quixote uses a special test frame for its tests, so you'll need to create and destroy it using quixote.createFrame() and frame.remove(). This is a relatively slow operation, so try to do it just once for each file you test.
If you modify the contents of the test frame, you can reset it to a pristine state by calling frame.reset() or frame.reload(). This is faster than recreating the test frame.
Unit Test Style
In the unit test style, you create a frame that loads your CSS file and use `fra
Related Skills
node-connect
346.8kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
107.6kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
346.8kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
346.8kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
