Look, this isn't that hard. In order to test my
<apply-author-styles>
Polymer element, I need a test page that:- holds a test Polymer element that uses
<apply-author-styles>
- Can run in a server so that XHR request can be made
- Has custom styles that can be pulled from the page into the test custom element
So you know what? I give up. I'm testing with Dart.
I already have Grunt setup in this project, so I stick with it here. In this case, I want a simple static server against which to run my tests (there is a simple Ajax component). I already have that in the form of
grunt-contrib-connect
. Now I need a way to run Dart tests against this JavaScript element (yes, I'm serious). Since there is no grunt-contrib-dart yet (why not?!), I install
grunt-shell
:$ npm install --save-dev grunt-shellThen I add this to the imported tasks in my
Gruntfile.js
and define my test_runner.sh shell task that will run my Dart tests:module.exports = function(grunt) { // Project configuration. grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), // ... connect: { server: { options: { port: 8100, keepalive: false } } }, shell: { test: { command: 'test/test_runner.sh' } } }); grunt.loadNpmTasks('grunt-contrib-watch'); grunt.loadNpmTasks('grunt-shell'); grunt.loadNpmTasks('grunt-contrib-connect'); grunt.registerTask('default', ['connect', 'shell:test']); };The
test_runner.sh
script is a simple fork of content_shell
that comes bundled with Dart for headless testing—but real headless testing with an actual browser. The test_runner.sh
script looks like:#!/bin/bash # Run a set of Dart Unit tests results=$(content_shell --dump-render-tree http://localhost:8100/test/ 2>&1) echo -e "$results" # check to see if DumpRenderTree tests # fails, since it always returns 0 if [[ "$results" == *"Some tests failed"* ]] then exit 1 fi echo echo "Looks good!"OK with that, I have my runner in place. Grunt will start
grunt-contrib-connect
as part of the default task and content_shell
will run my test at http://localhost:8100/test/. Now I just need to define the test.I start with a test context page that *I* can write:
<head> <!-- Load Polymer --> <script src="/bower_components/platform/platform.js"></script> <!-- Load component(s) --> <link rel="import" href="x-foo.html"> <!-- Style that will apply to both page and Polymer elements --> <style> button { border: 5px solid orange; } </style> </head> <body> <div id=test><!-- Test element --> <x-foo></x-foo> </div> <div id=page><!-- Page element --> <button type=button>Test in Main Page</button> </div> </body>In there, I have the page style—orange buttons—that I want to apply to my
<x-foo>
test element that makes use of <apply-author-styles>
. The <x-foo>
element was defined a couple of days ago as:<link rel="import" href="polymer/polymer.html"> <link rel="import" href="apply-author-styles/apply-author-styles.html"> <polymer-element name="x-foo" noscript> <template> <apply-author-styles></apply-author-styles> <button id=test type=button>Test</button> </template> </polymer-element>That
<apply-author-styles>
should change the style of the button inside the element (something the old, deprecated applyAuthorStyles
Polymer property used to do). I don't need to actually test that the button is orange. I may try that another day, but for now, I just need to know that that page style has been copied to the shadow DOM of my element. Or, in test form:library main_test; import 'package:scheduled_test/scheduled_test.dart'; import 'dart:html'; main(){ group("[styles]", (){ test('the app returns OK', (){ var xFoo = query('x-foo'); expect(xFoo.shadowRoot.text, contains('orange')); }); }); }Which does the trick:
CONSOLE MESSAGE: unittest-suite-wait-for-done CONSOLE MESSAGE: PASS: [styles] the app returns OK CONSOLE MESSAGE: All 1 tests passed. CONSOLE MESSAGE: unittest-suite-successThat is not quite perfect—there is some discrepancy between running it in the browser and from content_shell that bears some investigation. Still, it is so very nice to have a testing framework that runs in the browser, can test easily against a custom page context, and actually passes.
As crazy as it might seem to run a Dart test runner for JavaScript code, the crazier thing might be fighting ever more obscure JavaScript testing frameworks. So I may end up sticking with this.
Day #98
Soon you too will join the Dart side.
ReplyDelete