Chasing The Dream of Style Guide Driven Development in Drupal 8

Brian Perry

Breakthrough Technologies

Brian Perry

@bricomedy / brianperry

Breakthrough Technologies

http://breaktech.com

So what exactly is Style Guide Driven Development anyway?

Decoupling of front and back end development

Theming doesn't have to come last

Perception

 

 

 

 

 

 

Reality

 

 

 

 

 

 

(Mario Kart Version)

 

 

 

 

 

 

The Living Style Guide

A Living Style Guide

  1. Is modular and re-usable
Atomic Design - design systems of components, not pages
Atomic Design Overview

A Living Style Guide

  1. Is modular and re-usable
  2. Uses real world css and markup
  3. Is always kept up to date
  4. Is testable

Has this ever happened to you?

Infomercial Saran Wrap Fail

One tiny css change causes a regression deep in the outer reaches of your site

(and, it goes unnoticed for lord knows how long)

Visual Regresison Diff for Teaser

Get to the Drupals Already...

Drupal 8 wants you to build better themes

Cleaner Markup

Base Themes

  • Classy
  • Stable

Clearer seperation between logic and display


{%
	set classes = [
		'block',
		'block-' ~ configuration.provider|clean_class,
		'block-' ~ plugin_id|clean_class,
	]
%}
< div {{ attributes.addClass(classes) }}>
						

(From block.html.twig)


{% if attributes.hasClass('myClass') %}
  {# do stuff #}
{% endif %}
            

Tools to Create Modular, Re-usable components

CSS Coding Standards

Seven CSS Folder Structure

SMACSS

  1. Base
  2. Layout
  3. Component (aka Module)
  4. State
  5. Theme (aka Skin)

BEM

Naming convention for components

  • Block
  • Element
  • Modifier

.block {}
.block__element {}
.block--modifier {}
.block__element--modifier {}
						
Seven Pager Components

Twig Extends

field.html.twig

Default field.html.twig

Twig Blocks

Custom field.html.twig

Custom Field Template With Blocks

Twig Extends

field--field-hero-header.html.twig

Extended Field Template

Creating Your Style Guide

Style Guide API

hook_styleguide()

hook_styleguide_alter()

Customized Style Guide Components
Customized Style Guide Categories

Style Guide D8 Port In-Progress

https://www.drupal.org/node/2606942

Style Guide Generators to the Rescue

Many options

  • Pattern Lab
  • Hologram
  • KSS

KSS

  • Human readable documentation syntax
  • Any flavor of CSS
  • Node JS implementation
  • Grunt plugin

Install

(There's a module for that...)

npm install kss --save-dev

npm install grunt-kss --save-dev

Example

Homepage Solutions Section

KSS Syntax


// Solution Teaser
//
// A teaser for solutions taxonomy as displayed on the homepage
//
// Markup: kss_markup/solution_teaser.html
//
// Style Guide: Solutions.Teaser
.view-solutions .views-row {
  .views-field-field-category-icon .col-xs-3 {
    padding: 3%;
    border-radius: 50%;
    background-color: $gray_light;
    img {
      @extend .img-responsive;
    }
  }
}
            

Build Style Guide

grunt kss

or:

kss-node --source sass --destination styleguide --css css/style.css

KSS Solutions Teaser Output

Testing Your Style Guide and Theme

Behat

Behavior Driven Development Framework


@javascript
Scenario: Footer style matches style guide
  Given I am an anonymous user
  And I am on "assessments/practice-assessments"
  When I am browsing using a "phone"
  Then "body" should have a "background-color" css value of "rgb(112, 84, 125)"
  And "#page" should have a "background-color" css value of "rgb(255, 255, 255)"
  And "footer" should have a "padding-top" css value of "50px"
  And "footer" should have a "padding-bottom" css value of "30px"
            

View Gist for detail of steps

BBC Mobile Screenshot Diff

Wraith

Screenshot Comparison Tool

  • Compares two URLs
  • Simple configuration
  • Typically 'all or nothing' diffs
Wraith Screenshot Report

Phantom CSS

CSS Regression Testing

Phantom CSS Diff Screenshot
  • PhantomJS/SlimerJS - Headless Browser
  • CasperJS - Navigation and Scripting
  • ResembleJS - Screenshot Comparison

Strengths: interactivity, easier to target components.

WebdriverIO

Selenium Bindings for NodeJS

WebdriverIO Robot Logo
  • Selenium - Browser Automation
  • WebdriverIO - Node library to drive selenium
  • WebdriverCSS - CSS Regression Testing

Strengths: interactivity, easier to target components.

Install

npm install webdriverio@3.4.0 webdrivercss@2.0.0beta-rc1 selenium-standalone --save-dev

./node-modules/.bin/selenium-standalone install

Creating a Test

wdio-tests.js


var wdio = require("webdriverio");
var webdrivercss = require("webdrivercss");
var assert = require("assert");

var options = {
  desiredCapabilities: {
    browserName: "chrome"
  }
}
var browser = wdio.remote(options);
webdrivercss.init(browser, {
  screenshotRoot: "screenshots"
});

function assertShots (err, shots) {
  assert.ifError(err);

  Object.keys(shots).forEach(function(element) {
    shots[element].forEach(function(shot) {
      assert.ok(shot.isWithinMisMatchTolerance, shot.message);
    })
  });
};
            

browser
  .init()
  .url("http://breaktech.dev.dd:8083/")
  .webdrivercss("solutions", [
    {
      name: "solution teaser",
      elem: ".view-solutions .views-row:first-child"
    }
  ], assertShots)
  .click(".fa-bars")
  .webdrivercss("navigation", [
    {
      name: "Off Canvas Menu",
      elem: ".sidebar-offcanvas"
    }
  ], assertShots)
  .end();
            
Phantom Generated Screenshot of Solutions Teaser

Chasing the dream?

Still Chasing...

  • My workflow - tools continue to evolve
  • Component Based Rendering Initiative
  • Drupal and Style Guide Sharing Markup
Zen Theme
MVC vs MVP diagram

Component Based Rendering Initiative

https://www.drupal.org/node/2702061

drupaltwig.slack.com #components

Questions?